Вы находитесь на странице: 1из 281

PIMCD2013-python

Publicacin 1.0

Luis Miguel Snchez Brea

March 10, 2015


ndice general

1. Introduccin 3
1.1. Precedentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Por qu Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3. Python vs. Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.4. Python en el mbito cientfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2. Puesta en Marcha 9
2.1. Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3. Consolas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4. IDEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5. Pythonpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6. Ayudas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7. Autoejecucin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.8. Cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.9. Generacin de ayudas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.10. Carga de Mdulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.11. Definicin de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.12. Cdigo ejecutable: main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.13. Sistema de verificacin del cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3. Lenguajes de Programacin 29
3.1. Caractersticas de programacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4. Mdulos Cientficos 37
4.1. Numpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.2. Scipy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3. Matplotlib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

5. Ecuaciones de Maxwell en el vaco 71


5.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.2. Programacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.3. Haces de Gauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

6. Polarizacin 81
6.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2. Programa interactivo para el anlisis de la polarizacin . . . . . . . . . . . . . . . . . . . . . . . 82
6.3. Definiciones de polarizadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.4. Definiciones de estados de luz polarizada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.5. Clculo de la intensidad de un vector de polarizacin . . . . . . . . . . . . . . . . . . . . . . . . 86
6.6. Polarizacin bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.7. Ley de Malus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.8. Efecto Zenon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

I
7. Interaccin radiacin-materia 91
7.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.2. Dipolo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
7.3. Resonancia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.4. Densidad espectral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
7.5. Seccin eficaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

8. ndice de refraccin: modelo microscpico 103


8.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.2. ndice de refraccin para cargas ligadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.3. Aproximacin de Sellmeier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.4. Aproximacin de Cauchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
8.5. Frecuencia de plasma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

9. Ecuaciones de Fresnel 117


9.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
9.2. Funciones para calcular las ecuaciones de Fresnel . . . . . . . . . . . . . . . . . . . . . . . . . . 119
9.3. Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.4. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
9.5. Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

10. Pulsos de luz 129


10.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
10.2. Espectros de distintos tipos de pulso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
10.3. Suma de dos ondas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

11. Interferencias 137


11.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
11.2. Programacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
11.3. Interferencia entre dos ondas plana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
11.4. Interferencia entre dos haces de Gauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
11.5. Interferencia entre dos ondas esfricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

12. Mdulos de ptica 157


12.1. Clase camposXY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
12.2. Clase fuentesXY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
12.3. Clase mascarasXY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

13. Difraccin en campo cercano 191


13.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
13.2. Programacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
13.3. Difraccin por una abertura cuadrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
13.4. Difraccin por una abertura cuadrada: varias distancias . . . . . . . . . . . . . . . . . . . . . . . 195
13.5. Difraccin por una abertura circular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
13.6. Difraccin por un borde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
13.7. Difraccin por una doble rendija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
13.8. Difraccin por una lente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
13.9. Difraccin por una lente binaria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

14. Difraccin en campo lejano 209


14.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
14.2. Difraccin por un cuadrado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
14.3. Difraccin por una rendija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
14.4. Difraccin por un crculo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
14.5. Difraccin por una doble rendija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
14.6. Difraccin por una estructura complicada: estrella . . . . . . . . . . . . . . . . . . . . . . . . . 217
14.7. Difraccin por una estructura complicada: fotografa . . . . . . . . . . . . . . . . . . . . . . . . 218
14.8. Difraccin por una red de sinusoidal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
14.9. Difraccin por una red de Ronchi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

II
14.10. Propiedades de la transformada de Fourier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

15. Redes de Difraccin 233


15.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
15.2. Red Sinusoidal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
15.3. Red de Ronchi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
15.4. Red de Binaria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
15.5. Red Blazed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
15.6. Red bidimensional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
15.7. Red tipo Ajedrez . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
15.8. Red radial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
15.9. Red angular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
15.10. Red con borde sinusoidal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
15.11. Red hiperblica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
15.12. Aplicacin como redes de difraccin en campo lejano . . . . . . . . . . . . . . . . . . . . . . . 247
15.13. Efecto Talbot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
15.14. Efectos con dos redes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253

16. Procesado ptico de la informacin 259


16.1. Funcionamiento de la clase procesadoOptico . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
16.2. Filtro pasa baja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
16.3. Eliminacin de ruido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
16.4. Filtro pasa alta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
16.5. Filtro pasa banda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
16.6. Filtro de contraste de fase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273

III
IV
PIMCD2013-python, Publicacin 1.0

ndice general 1
PIMCD2013-python, Publicacin 1.0

2 ndice general
CAPTULO 1

Introduccin

Autores Jos Mara Herrera Fernndez, Luis Miguel Snchez Brea

Contenidos de este captulo:


Precedentes
Por qu Python?
Python vs. Matlab
Python en el mbito cientfico

1.1 Precedentes

El manejo de aplicaciones informticas, actualmente generalizado, no conlleva realmente el dominio de las nuevas
tecnologas informticas. La programacin y simulacin se ha convertido en una tarea necesaria en la sociedad
y en el mbito cientfico-tcnico, y por supuesto en el mbito acadmico. Sin embargo, la gran mayora de los
alumnos que llegan a los primeros cursos universitarios no tienen ninguna experiencia en programacin. Incluso en
cursos superiores, un porcentaje demasiado alto no han ido ms all de los ejercicios propuestos en las asignaturas
obligatoras de clculo numrico.
Dentro de la asignatura ptica del grado en Fsica de la Universidad Complutense de Madrid, Luis Miguel
Snchez Brea y Jos Mara Herrera Fernndez (profesor de la asignatura y alumno-tutor respectivamente) in-
corporaron en el curso 2011 - 2012 una serie de seminarios de Computacin cientfica de fenmenos pticos
basados en el lenguaje de programacin Python. Los seminarios se enfocaron como apoyo al aprendizaje de p-
tica utilizando la programacin como medio de resolucin de ejercicios en ptica y fueron la semilla para este
proyecto docente donde pretendemos presentar ejemplos sencillos y de fcil comprensin del uso de Python como
herramienta en diferentes mbitos.

1.2 Por qu Python?

Python es un lenguaje de programacin moderno, de alto nivel, ideal para pequeas aplicaciones as como para
proyectos de gran envergadura. El cdigo de Python es similar al pseudocdigo utilizado para esquematizar la
programacin. Permite realizar todo lo necesario para una programacin completa: diseo orientado a objetos,
unidades de testeo, generacin de documentacin en el cdigo, sencilla interaccin con el sistema operativo, etc.
Es compatible con la programacin basada en objetos, as como la estructurada y por eventos. Tiene un excelente
conjunto de libreras para extender su funcionalidad, incluyendo libreras cientficas que permiten realizar nume-
rosas tareas de tratamiento de datos, visualizacin, clculo numrico y simblico y otras aplicaciones especficas.
Adems, existe una comunidad muy grande de usuarios que, debido a la filosofa open source, son mucho ms
proclives a compartir su cdigo.
A la hora de empezar a trabajar en computacin lo primero que nos sorprende es la gran cantidad de lenguajes
de programacin, por lo que se debe realizar una seleccin cuidadosa. Una lista de los lenguajes de programacin

3
PIMCD2013-python, Publicacin 1.0

ms utilizados se puede encontrar en la Figura 1.

Figura 1.1: Figura 1. Lenguajes de programacin ms utilizados en el mundo. Python se mantiene es-
table como tercer lenguaje de programacin despus de la familia de C y de Java. Adems com-
parndo con un lenguaje de mbito cientfico como MATLAB, su posicin es notablemente superior
(4,3 % de uso frente a 0,6 %). Fuente: TIOBE Programming Community Index for November 2013,
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html .

Por un lado existen lenguajes de uso muy extendido. Actualmente Java es el lenguaje ms utilizado, pues se
utiliza para aplicaciones corporativas. El segundo lenguaje es C en sus diferentes versiones, un estndar en la
programacin durante muchsimos aos. La mayor parte de las ms famosas aplicaciones de escritorio estn
escritas en C++. Estos dos lenguajes dominan el negocio de la programacin. PHP domina en la red. Mientras Java
lo utilizan las grandes organizaciones, PHP lo utilizan empresas ms pequeas e individuos para crear aplicaciones
web dinmicas. Por otro lado, hay numeros paquetes numricos como Matlab, Mathematica y Maple que se
utilizan en centros de investigacin.
La gran mayora de los alumnos que llegan a los primeros cursos de Fsica no han programado nada o casi nada.
Es por ello que hemos elegido un lenguaje de programacin lo ms sencillo y completo posible. Python nos
ofrece una gran sencillez de programacin, una gran cantidad de libreras en las que basar nuestros programas y

4 Captulo 1. Introduccin
PIMCD2013-python, Publicacin 1.0

una importante comunidad de usuarios y desarrolladores que lo soportan. Tambin tiene la ventaja de ser open
source, por lo no nos vamos a tener que asumir ningn coste debido a derechos de autor. Otra ventaja es ser un
sistema multiplataforma, as que podremos programar en cualquier sistema operativo como Windows, Linux o
Mac Os.
Veamos resumidas algunas de las ventajas del lenguaje de programacin Python.
Python es un lenguaje de programacin de alto nivel que permite una rpida implementacin de aplicaciones
con muy poco cdigo. Es ideal para prototipado rpido, pero tambien permite el desarrollo de grandes
aplicaciones.
El cdigo de Python es legible, muy similar al pseudocdigo utilizado para esquematizar la programacin.
Python es un lenguaje interpretado por una mquina virtual, no compilado, por lo que es multiplataforma.
Python permite realizar todo lo necesario para una programacin de cdigo moderna: diseo orientado a
objetos, unidades de testeo, generacin de documentacin en el cdigo, sencilla interaccin con el sistema
operativo, etc.
Tiene estructuras de datos de alto nivel, como las listas, tuplas y diccionarios
Permite la programacin basada en objetos, aunque tambien soporta la programacin funcional y la progra-
macin estructurada.
Es un lenguaje dinmico, pudiendose aadir nuevas funciones y clases a un objeto existente, incluso en
tiempo de ejecucin.
Existen libreras cientficas escritas en Phython maduras y con gran capacidad.
Permite extender trivialmente su aplicabilidad con mdulos escritos en C, C++ y Fortran, de los que existen
numerosas libreras cientficas. Al ser los procedimientos ms rpidos y eficientes para desarrollo de algo-
ritmos matemticos (aunque a veces mucho ms complicados para otras tareas), se pueden programar las
partes ms sensibles en C y realizar el resto de la aplicacin en Python
Tiene un enorme conjunto de libreras para extender su funcionalidad: para acceseo a base de datos, para
almacenamiento de datos, para procesamiento de imgenes, de sonido, para programacin con GUIs (Inter-
faces grficas de usuario, ventanas), y otras muchisimas ms.
Permite el acceso a toda la funcionalidad del sistema operativo (sobre todo en Linux).
Python se puede utilizar como software glue para combinar distintas aplicaciones en una sola (sobre todo
el Linux).
El uso de la indentacin en lugar de los parntesis permite una mayor legibilidad del cdigo.
El cdigo Python se escriben en archivos .py. Estos archivos se pueden agrupar en mdulos, y se pueden
importar los elementos de los mdulos a otros archivos.
Para sistemas Unix, se puede utilizar cdigo para hacer el archivo autoejecutable indicando al sistema que
programa que el es un ejecutable (no hace falta que sea un archivo .exe). utilizar (#!)
El cdigo es extraordinariamente sencillo de comprender.
Existen mdulos de gran calidad y repositorios de cdigo donde se puede encontrar numerosas aplicaciones.
En linux, gran parte de los mdulos estn en los repositorios estndar, por lo que su instalacin es tn sencilla
como pulsar un botn.
Existe una comunidad muy grande de usuarios y debido a la filosofa open, los desarrolladores son mucho
ms proclives a compartir su cdigo con otros. Adems no suelen existir problemas de uso del cdigo de
otros, siempre que cumplas los requisitos de la licencia GLS.
Al ser Python un lenguaje de propsito general, el cdigo que se genera se puede aprovechar de las ventajas
de otros mdulos (como comprimir archivos, enviar datos, automatizar procesos, enlazar nuestros datos con
bases de datos, con servidores web....
Python se puede ejecutar en bastantes IDEs (editores), desde algunos muy sencillos, como IDLE, hasta otros
tan completos como Spyder, Eclipse o NetBeans.

1.2. Por qu Python? 5


PIMCD2013-python, Publicacin 1.0

Existen diversas tcnica para creas sistemas de ventanas (Tkinter, wx, QT, etc.) de una forma sorprendente-
mente sencilla en comparacin con otros sistemas operativos. Si se nos da bien el curso, intentaremos ver
QT4, a travs de la herramienta de creacin de ventanas QT Designer 4.

1.3 Python vs. Matlab

MATLAB (abreviatura de MATrix LABoratory, laboratorio de matrices) es un software matemtico que ofrece
un entorno de desarrollo integrado (IDE) con un lenguaje de programacin propio (lenguaje M). Est disponible
para las plataformas Unix, Windows y Apple Mac OS X. Entre sus prestaciones bsicas se hallan: la manipulacin
de matrices, la representacin de datos y funciones, la implementacin de algoritmos, la creacin de interfaces de
usuario (GUI) y la comunicacin con programas en otros lenguajes y con otros dispositivos hardware. El paquete
MATLAB dispone de dos herramientas adicionales que expanden sus prestaciones, a saber, Simulink (plataforma
de simulacin multidominio) y GUIDE (editor de interfaces de usuario - GUI). Adems, se pueden ampliar las
capacidades de MATLAB con las cajas de herramientas (toolboxes); y las de Simulink con los paquetes de bloques
(blocksets). Matlab tiene ventajas muy interesantes para la programacin cientfica.
Las sesiones interactivas permiten jugar con los datos de una forma muy sencilla.
La sintaxis est muy bien desarrollada para trabajar con vectores y matrices.
La capacidad de visualizacin de datos y modificacin de figuras es excepcionalemente buena.
Existen libreras (normalmente propietarias) de gran calidad y existe una comunidad muy grande de usua-
rios.
No obstante, la mayor parte de estas ventajas tambin las tiene Phython. Adems, tiene una serie de desventajas
que lo desaconsejan como primer lenguaje de programacin.
En primer lugar no es un lenguaje de programacin verdadero ya que est muy dedicado al clculo numri-
co, aunque su funcionalidad se ha extendido con numerosas toolboxes (control de bases de datos, interaccin
con el sistema operativo, etc...).
Adicionalmente, es un lenguaje propietario que requiere de licencias excesivamente caras para estudiantes.
No se puede ejecutar cdigo de forma independiente (standalone). NOTA: Recientemente se ha proporcio-
nado una herramienta adicional llamada MATLAB Builder bajo la seccin de herramientas Application
Deployment para utilizar funciones MATLAB como archivos de biblioteca que pueden ser usados con
ambientes de construccin de aplicacin .NET o Java.
Es horrible hacer un cdigo largo, pues cada funcin debe estar en un nico archivo. Esto significan miles
de archivos y hace ms complicado que varios programadores trabajen en el mismo cdigo.
Tambin Python tiene algunas desventajas respecto a Matlab:
No es tan sencillo manipular las figuras en tiempo real.
Al existir una cantidad ingente de programadores que aportan su cdigo de forma libre, a veces es dificil
determinar cuales son los mdulos mejores para una cierta aplicacin. Hay ms posiblidades donde elegir.

1.4 Python en el mbito cientfico

Python es un lenguaje de programacin de propsito general que, en un principio, no se pens para aplicacio-
nes cientficas. Con los aos, siguiendo la filosofa GNU, se han desarrollado multitud de mdulos cientficos,
que permiten realizar numerosas tareas de tratamiento de datos, visualizacin, clculo simblico y aplicaciones
cientficas especficas. Nosotros utilizaremos fundamentalmente los siguientes mdulos cientficos:
Numpy: Generacin de tipos de datos cientficos. http://www.numpy.org/
Scipy: Funciones cientficas de uso general. http://www.scipy.org/
Matplotlib: Grficas en 2D y 3D. http://matplotlib.org/
Mayavi: visualizacin de datos tridimensionales. http://code.enthought.com/projects/mayavi/

6 Captulo 1. Introduccin
PIMCD2013-python, Publicacin 1.0

Visual Python: Permite realizar representaciones tridimensionales de objetos en movimiento.


http://www.vpython.org/
SymPy: Clculo simblico. http://sympy.org/en/index.html
Opencv: Biblioteca libre de visin artificial en C cuyas libreras se han adaptado a Python.
http://opencv.willowgarage.com/documentation/python/
Meep: clculo de Diferencias finitas en el dominio del tiempo. http://ab-initio.mit.edu/wiki/index.php/Meep.
NOTA: Existe un enlace (binding) para Python, de forma que se puede programar dicho mdulo de una
manera mucho ms sencilla, https://launchpad.net/python-meep.
Existen asimismo otros muchos mdulos bastante maduros escritos en Python como OpenFilters para el dise-
o de filtros interferenciales, http://www.polymtl.ca/larfis/English_Version/OF/OF_English.htm y Empy donde se
implementa la tcnica de RCWA, http://empy.sourceforge.net. Para ms informacin el lector puede consultar el
siguiente enlace http://www.scipy.org/topical-software.html donde podr encontrar otros modulos de inters.

1.4. Python en el mbito cientfico 7


PIMCD2013-python, Publicacin 1.0

8 Captulo 1. Introduccin
CAPTULO 2

Puesta en Marcha

Autores Jos Mara Herrera Fernndez, Luis Miguel Snchez Brea

Contenidos de este captulo:


Windows
Linux
Trabajar con Python
Consolas
IDEs
Pythonpath
Ayudas
Mi primer programa
Estructura de un programa .py
Autoejecucin
Cabecera
Generacin de ayudas
Carga de Mdulos
Definicin de funciones
Cdigo ejecutable: main
Sistema de verificacin del cdigo

Como en casi todos los programas, dependiendo del sistema operativo del que disponga nuestro ordenador la
instalacin de software variar ligeramente y Python no es una excepcin. A fin de que el sistema operativo no
suponga un bache en nuestro camino hacia el aprendizaje de Python, en esta seccin veremos la instalacin paso a
paso en los dos sistemas operativos ms extendidos en la actualidad. Para otros sistemas operativos recomendamos
al lector que en caso de duda acuda a la gran bibliografa existente en la red.

2.1 Windows

A la hora de instalar Python en el sistema operativo de Microsoft tenemos dos opciones segn el uso que vayamos
a hacer del lenguaje de programacin. Por una parte, como ya hemos mencionado en la introduccin, Python es un
leguanje de programacin de uso general por lo que, si ste es el caso, recomendamos la instalacin del paquete
bsico e incorporar los mdulos que necesitemos. En el sitio oficial de Phython en la seccin de descargas podemos
encontrar diferentes versiones. En la actualidad conviven las versiones 3.3.* y 2.7.* donde * es la ltima versin
estable. Las instalaciones de este libro fueron realizadas con la versin 2.7.2 aunque no vara sustancialmente
para versiones posteriores. Por otra parte, como la programacin que vamos a realizar est orientada al mbito
cientfico-acadmico e ingenieril, la opcin que ms se ajusta a nuestros intereses es el paquete Python(x,y).
Python(x,y) es un software de desarrollo gratuito que incorpora los principales mdulos necesarios para clculo
numrico junto con algn otro complemento que analizaremos posteriormente. La instalacin es similar a otros
programas de Windows. Lo primero que debemos de hacer es descargarmos la ltima versin del programa desde
la seccin de descargas de la web oficial, http://code.google.com/p/pythonxy/wiki/Downloads?tm=2.

9
PIMCD2013-python, Publicacin 1.0

En la Figura 2 podemos ver que en el mismo enlace disponemos de las notas de instalacin que recomendamos
repasar antes de iniciar el proceso. Son unos 420 MB (ya que tiene bastantes aplicaciones). Una vez instalado
observaremos como nuestros archivos con extensin .py se asocian con python por lo que si pinchamos dos veces
sobre ellos se ejecutarn.

Figura 2.1: Figura 2. Descarga de Python(x,y) desde la seccin correspondiente en la web oficial. En las misma
pgina podemos encontrar las notas de instalacin que debemos de tener en cuenta.

2.2 Linux

Python viene incorporado en la mayora de las distribuciones existentes. Si en una terminal ejecutamos el comando
python - V

comprobaremos que versin de Python tenemos instalada. En caso de no ser as podemos instalarlo ejecutando
apt-get install python

Otra opcin es, por ejemplo, desde el centro de software en Ubuntu. Basta con buscar python en el lugar co-
rrespondiente y nos indicar si lo tenemos instalado y si queremos instalarlo o desistalarlo. Para instalar nuevos
mdulos se puede seguir el mismo procedimiento ya sea desde la terminal o desde el centro de software.

2.2.1 Trabajar con Python

A la hora de iniciarse en la programacin es muy importante conocer la sintasis del lenguaje que se va a utilizar
para desarrollar codigo de una manera correcta. De igual importancia es conocer las herramientas de las que
disponemos para ejecutar y depurar el cdigo desarrollado.

2.3 Consolas

Desde el mismo momento en el que Python se instala en el sistema podemos empezar a programar abriendo una
consola interactiva en una terminal. La consola interactiva ms sencilla se ejecuta directamente en un terminal
(Linux) escribiendo
python

10 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

Inmediantamente podremos ir introduciendo lineas de comandos y ejecutar de una en una. En Windows la forma
es equivalente.
Existen concolas interactivas ms completas que nos van indicando ayudas inmediatas a medida que vamos escri-
biendo cdigo. Se introduce la instruccion y se ejecuta de una en una. Esta forma de programacin es adecuada
cuando somos principiantes y estamos desarrollando programas cortos donde nos interesa ver inmediatamente si
el resultado es correcto o no.

2.4 IDEs

Las consolas no es el mejor procedimiento para desarrollar programas extensos. El cdigo escrito en la consola
no es fcil de seguir y de volver a utilizar. Una programacin eficaz se realiza mediante un Entorno de Desarro-
llo Integrado (IDE, Integrated Developed Environment). Con este acrnimo ingls se describe a toda aplicacin
de sofware que proporciona una facilidad comprensiva a la hora de la creacin de programas informticos sea
en el lenguaje que sea. Normalmente un IDE consta de un editor de cdigo fuente, un compliador y/o un intr-
prete, herramientas de creacin y un depurador. Tambin suelen tener consolas interactivas. En esta seccin nos
centraremos en tres IDEs en particular: IDLE, Spyder y Eclipse.
IDLE: es el IDE de Python basado en el entorno de ventantas thinter y desarrollado 100 % tambin en
Python. Es el ms simple de los tres que veremos pero para principiantes quizs sea el ms adecuado. Posee
modo depuracin aunque para programadores experimentados se queda bastante corto. La instalacin en
Windows se realiza con la instalacin del propio lenguaje mientras que en el resto de SO la instalacin se
realiza de la forma usual. Para ms informacin podemos consultar la documentacin oficial en el siguiente
enlace: http://docs.python.org/2/library/idle.html. En la Figura 3 se muestra un ejemplo de creacin de un
array en la consola de IDLE.
Spyder: Spyder es un IDE especfico para Python orientado a cientficos y desarrollo ingenieril con una
interfaz muy similar a Matlab, por lo que es la opcin ms adecuada cuando se quiere migrar de Matlab
a Python. Si hemos instalado Python(x,y), al iniciar el programa se nos abre una ventana con diversas
caractersitcas. Dentro de la pestaa Shortcuts nos encontramos el apartado Spyder. Bastar con pinchar
en el smbolo del programa (Figura 4) e inmediatamente se nos abrira el programa. Como siempre, si nos
encontramos en linux abrimos una terminal y ejecutamos la orden
sudo apt-get install spyder

y tras unos segundos nos aparecer como opcin en nuestro menu.


Al iniciar el programa por primera vez vemos que, si hemos sido usuarios de MATLAB, efectivamente nos encon-
tramos en un entorno familiar. En la Figura 5 vemos que en la zona izquierda de la pantalla tenemos un editor de
cdigo. En la zona central nos encontramos un navegador con nuestros programas y en la zona derecha tenemos
la ayuda y la consola interactiva.
Para ms informacin podemos consultar el manual oficial del IDE en http://packages.python.org/spyder/
Eclipse: Eclipse es un programa informtico compuesto por un conjunto de herramientas de programacin
de cdigo abierto multiplataforma para desarrollar lo que el proyecto llama Aplicaciones de Cliente Enri-
quecido, opuesto a las aplicaciones Cliente-liviano basadas en navegadores. Esta plataforma, tpicamente
ha sido usada para desarrollar IDEs, como el IDE de Java llamado Java Development Toolkit (JDT). Eclipse
puede ser usado con Python mediante la instalacin de Pydev. Pydev es un IDE para Eclipse muy com-
pleto y configurable con un modo de depuracin extraordinariamente potente. De los tres IDEs que hemos
visto, ste es el entorno ms complicado por la cantidad de opciones que contiene. Sin embargo para el
programador avanzado ser el que ms comodo le resulte a la hora de realizar sus programas.
Si nos encontramos en el sistema operativo de Microsoft, lo primero que debemos hacer es decargarnos la ultima
versin del programa en el sitio oficial, http://www.eclipse.org/downloads/. En linux,
sudo apt-get install eclipse

Tanto en linux como en Windows si no los tenemos debemos instalar la ultima versin de Java Development Kit
(JDK) y el Java Runtime Environment (JRE). Para configurar PyDev en Eclipse debemos de seguir los siguientes
pasos:

2.4. IDEs 11
PIMCD2013-python, Publicacin 1.0

Figura 2.2: Figura 3. Consola de IDLE.

12 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

Figura 2.3: Figura 4. Spyder en Python(X,Y). Para iniciar el programa pinchamos en el smbolo resaltado en la
imagen.

2.4. IDEs 13
PIMCD2013-python, Publicacin 1.0

Figura 2.4: Figura 5. Spyder con sus diferentes secciones.

1. Abrimos Eclipse y nos vamos a Help -> Install New Software. En la pantalla emergente aadimos
http://pydev.org/updates en el campo work with.
2. Pulsamos en Add, esperamos a que actualize el campo de abajo para poder seleccionar PyDev, luego pulsa-
mos en Next, y seguimos el asistente para completar la instalacin.
3. Reiniciamos Eclipse.
4. Ahora deberemos especificar dnde se encuentra el interprete de python en las preferencias Eclipse, para
ello nos vamos a Eclipse -> preferences -> PyDev -> Interpreter > Python. Pulsamos en auto Config,
marcamos todo (sino lo est) y aceptamos.
En este caso tambin tenemos a nuestra disposicin un manual oficial muy completo en
http://pydev.org/manual_101_root.html. Si hemos realizado todos los pasos correctamente podremos ejecu-
tar programas realizados en python sin ningn problema. En la Figura [figEclipse] podemos ver un ejemplo de la
disposicin de las secciones en Eclipse. Estas seccciones son totalmente configurables por lo que dependiendo de
vuestras preferencias la imagen puede o no coincidir con vuestra disposicin.

2.5 Pythonpath

Dependiendo el IDE elegido se nos habr creado una carpeta como directorio de trabajo. Sin embargo en ocasiones
puede interesarnos trabajar con archivos fuera de este directorio. Para ello debemos de aadir la nueva ruta de
nuestros archivos. Esta operacin se realiza en Pythonpath.
Spyder:
Tools > PYTHONPATH manager.
Se busca el directorio donde tenemos los programas.
Eclipse:

14 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

Figura 2.5: Figura 6. Instalacion de Pydev en Eclipse.

Project > Properties >Pydev - PYTHONPATH.


Se busca el directorio donde tenemos los programas.

2.6 Ayudas

Las comandos de los lenguajes de programacin son prcticamente infinitos y, slo mediante prctica, consegui-
remos aprendernos algunos de ellos. Sin embargo, en la mayora de los casos debereos acudir a la documentacin
oficial para resolver nuestras dudas. Normalmente cada lenguaje de programacin tiene algn comando especfico
para acceder a la informacin que nos interese. Adems muchos de los IDE facilitan el acceso a esta informacin
mediante algn acceso directo o alguna ventana permanente. En general los pasos a seguir cuando no sabemos
qu comando utilizar o la sintaxis de su utilizacin son los siguientes.
Google. El buscador de informacin en internet por excelencia. En algunas ocasiones no sabremos muy
bien por donde empezar o nos sabremos el comando equivalente en otro lenguaje de programacin. Si el
lector ha tenido esa duda seguramente otra persona la haya tenido antes por lo que podremos encontrar la
respuesta sin demasiado esfuerzo.
Mediante el uso de comandos especificos. Como hemos mencionado, cada lenguaje de programacin tiene
una serie de comandos para accecer a la informacin de los comandos acerca de los cuales tengamos dudas.
Por ejemplo si en una consola tecleamos
import numpy as np

help(np.linspace)

obtendremos la informacin de linspace en la misma consola,


Help on function linspace in module numpy.core.function_base:

2.6. Ayudas 15
PIMCD2013-python, Publicacin 1.0

Figura 2.6: Figura 7. Instalacion de Pydev en Eclipse.

16 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

Figura 2.7: Figura 8. Instalacin de Pydev en Eclipse.

linspace(start, stop, num=50, endpoint=True, retstep=False)


Return evenly spaced numbers over a specified interval.

Returns num evenly spaced samples, calculated over the


interval [start, stop ].

The endpoint of the interval can optionally be excluded.

Parameters
----------
start : scalar
The starting value of the sequence.
stop : scalar
The end value of the sequence, unless endpoint is set to False.
In that case, the sequence consists of all but the last of num + 1
evenly spaced samples, so that stop is excluded. Note that the step
size changes when endpoint is False.
num : int, optional
Number of samples to generate. Default is 50.
endpoint : bool, optional
If True, stop is the last sample. Otherwise, it is not included.
Default is True.
retstep : bool, optional
If True, return (samples, step), where step is the spacing
between samples.

Returns
-------
samples : ndarray
There are num equally spaced samples in the closed interval
[start, stop] or the half-open interval [start, stop)
(depending on whether endpoint is True or False).
step : float (only if retstep is True)

2.6. Ayudas 17
PIMCD2013-python, Publicacin 1.0

Figura 2.8: Figura 9. Eclipse con Pydev configurado.

18 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

Figura 2.9: Figura 10. Carga de los directorios en el Pythonpath, para eclipse.

2.6. Ayudas 19
PIMCD2013-python, Publicacin 1.0

Size of spacing between samples.

See Also
--------
arange : Similiar to linspace, but uses a step size (instead of the
number of samples).
logspace : Samples uniformly distributed in log space.

Examples
--------
>>> np.linspace(2.0, 3.0, num=5)
array([ 2. , 2.25, 2.5 , 2.75, 3. ])
>>> np.linspace(2.0, 3.0, num=5, endpoint=False)
array([ 2. , 2.2, 2.4, 2.6, 2.8])
>>> np.linspace(2.0, 3.0, num=5, retstep=True)
(array([ 2. , 2.25, 2.5 , 2.75, 3. ]), 0.25)

Graphical illustration:

>>> import matplotlib.pyplot as plt


>>> N = 8
>>> y = np.zeros(N)
>>> x1 = np.linspace(0, 10, N, endpoint=True)
>>> x2 = np.linspace(0, 10, N, endpoint=False)
>>> plt.plot(x1, y, o)
[<matplotlib.lines.Line2D object at 0x...>]
>>> plt.plot(x2, y + 0.5, o)
[<matplotlib.lines.Line2D object at 0x...>]
>>> plt.ylim([-0.5, 1])
(-0.5, 1)
>>> plt.show()

En el caso concreto del IDE Spyder tenemos el Object inspector. Si escribimos en la caja object la palabra
que deseamos probablemente aparezca la ayuda de forma automtica. Por ejemplo, si quiero ordenar una
lista y no se cmo, podemos escribir sort y aparecer la forma de utilizacin. Adems tanto en spyder
como en Eclipse, al escribir el comando nos aparece la ayuda de forma automtica como podemos ver en la
Figura 11

2.6.1 Mi primer programa

Por tradicin se suele decir que un lenguaje de programacin es ms o menos complicado cuanto ms nos cuesta
implementar el Hola Mundo, es decir, imprimir en pantalla estas dos palabras. Python teniendo en cuenta este
criterio es de los lenguajes ms fciles ya que con una sola lnea de cdigo podemos obtener el resultado deseado
>>> print("Hola Mundo")
Hola Mundo

si comparamos con C++,


#include <iostream>

using namespace std;

int main() {

cout << "Hola Mundo" << endl;

return 0;

20 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

Figura 2.10: Figura 10. Ayuda automtica u Object inspector en Spyder.

2.6. Ayudas 21
PIMCD2013-python, Publicacin 1.0

vemos que el cdigo es notablemente ms largo. Por curiosidad y a modo de avance para el tema siguiente podemos
ver como se representa una grfica simple como la del seno en Python,
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Carga de los mdulos necesarios


import scipy as sp
import matplotlib.pyplot as plt

# Creamos el array x de cero a cien con cien puntos


x = sp.linspace(0, 10, 100)

# Creamos el array y conde cada punto es el seno de cada elemento de x


y = sp.sin(x)

# Creamos una figura


plt.figure()

# Representamos
plt.plot(x,y)

# Mostramos en pantalla
plt.show()

1.0

0.5

0.0

0.5

1.00 2 4 6 8 10

2.6.2 Estructura de un programa .py

En la seccin anterior hemos podido comprobar lo sencillo y legible que es un programa Python. No obstante,
con el fin de que el cdigo sea lo ms comprensible posible para cualquiera que se disponga a utilizarlo o modi-
ficarlo se suelen aadir por convenio una serie de apartados y lneas de cdico complementarias que facilitan su
comprensin. As, como normal general todos nuestros programas de Python deben tener los siguientes apartados

22 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

2.7 Autoejecucin
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

La primera lnea de cdigo sirve para decir al sistema operativo que este archivo se puede ejecutar, es decir,
si se hace click sobre el archivo, se llama al programa python y se ejecuta. Es el equivalente a los archivos
ejecutables .exe en Windows, aunque aqu el programa no est compilado, sino que se interpreta (esto ltimo
es ms lento).
La segunda lnea de cdigo sirve para poder utilizar la codificacion utf-8. De esta forma podemos poner
acentos, , etc.
La tercera lnea de cdigo carga un mdulo adicional que permite que la divisin entre nmeros enteros
pueda dar nmeros fraccionarios. Al ser Python un lenguaje de propsito general la divisin entre enteros da
lugar a enteros, lo cual suele ser problematico en clculos cientficos. NOTA: Tambin se puede solucionar
escribiendo, en lugar de 3/4, 3./4, pero de esta forma el riesgo de cometer errores por esta causa es menor.

2.8 Cabecera
# Nombre: ejemplo_estructura_programa.py
# Propsito: Ejemplo de archivo con la estructura de un programa
#
# Origen: Propio
# Autor: Jos Mara Herrera-Fernandez y Luis Miguel Sanchez Brea
#
# Creacin: 12 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, matplotlib
# Licencia: GPL

Esta seccin es estrictamente voluntaria, sin embargo es muy til cuando varios usuarios programan en el mismo
archivo.
Nombre > El nombre del archivo que vamos a crear cuando guardemos por primera vez. En nuestro caso
ejemplo_estructura_programa.py.
Propsito > La finalizad que se persigue al crear el programa, * Crear grfica del seno*, * Calcular los
coeficientes de un polinomio*, etc.
Origen > Si el origen del programa no es propio conviene saber su procedencia por si se debe consultar de
nuevo la fuente original en un futuro.
Autor(es) > Los nombres de los creadores del programa.
Creacin > Fecha de creacin del programa.
Historia > En caso de modificacines posteriores es en esta secin donde se indica la modificacin, la fecha
de la realizacin y el autor de la misma.
Dependencias > Mdulos necesarios para la ejecucin del programa. Por ejemplo scipy, matplotlib..
Licencia > Apartado correspondiente a los derechos de autor.
Como se observa, para incluir un comentario se utiliza el caracter #

2.7. Autoejecucin 23
PIMCD2013-python, Publicacin 1.0

2.9 Generacin de ayudas

En el apartado de Ayudas (2.2.4) aprendimos a utilizar el comando help para obtener informacin sobre el uso de
un determinado comando. El resultado es una informacin muy valiosa que nosotros debemos de aadir tambin
a nuestras funciones, programas etc. Es lo que se denomina Docstring. Las ayudas se deben de incluir inmediata-
mente despes de la cabecera en el caso de ser una descripcin general e inmediantamente despus de cualquier
funcin, clase, etc. La metodologa es simple, todo aquella informacin que creamos necesaria para el Docstring
debe de ir encerrada entre seis pares de comillas dobles (tres al inicio y tres al final). Adems para funciones
deberemos de incluir los siguientes apartados:
(Entradas) > (salidas). Se enumeran el tipo de entrados que necesita como entradas la funcin y el tipo de
salidas que nos devolver, int, bool, float, etc
Descripcin. Ecplicacin de la funcin.
Explicacin de cada entrada.
Explicacin de cada salida.
Test. Ejemplo sencillo con el resultado que pueda servir como comprobador del buen uso de la funcin
creada.
Ejemplo de ayuda para un archivo general,
"""
Descripcin: Archivo plantilla para generar programas en Python.

"""

Aunque todava no hemos visto las funciones podemos ver un ejemplo de ayuda en una funcin que nos devuelve
el seno del nmero que entremos,
def f1(x = 3.3):
"""
* (float) --> (float)
* Descripcin: Funcin que devuelve el seno de un entero dado.
* Entradas:
- x = entero.
* Salidas:
- y = seno(entero)
* Test:
>>> print("f1(0.7)")
0.64421768723769102
"""
y = sp.sin(x)
return y

2.10 Carga de Mdulos

En Python no es necesario declarar las variables, lo cual supone una gran simplificacin respecto a programas
como C. Sin embargo para llamar a funciones y clases que no estn en el archivo que se est ejecutando, es
necesario decirle dnde estn. Se pueden declarar un mdulo, o llamar a sus funciones de diversas formas. En los
siguientes ejemplos cargamos algunas o todas las funciones del mdulo cientfico scipy.
import scipy
import scipy as sp
from scipy import *
from scipy import sin
from scipy.fftpack import fft
import matplotlib.pyplot as plt

Veamos como llamaramos a la funcion sin dependiendo la forma en la que hayamos cargado scipy

24 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

import scipy > y = scipy.sin(x), Importamos scipy y llamamos a las funciones que tiene.
import scipy as sp > y = sp.sin(x), Renombramos scipy con un alias ms corto.
from scipy import * > y = sin(x), importamos todas las funciones que contiene scipy
from scipy import sin, cos > y = sin(x), importamos nicamente sin y cos
from scipy.fftpack import fft > Si los mdulos son muy largos, se pueden hacer en varios archivos. Entonces
las funciones o clases estn anidadas.
Esto es de gran utilidad por varios motivos:
Permite no estar pendiente del nombre de las funciones, clases, etc. Si el nombre se repite en dos mdulos,
no hay problema, pues sabemos a qu mdulo pertenece
Permite escribir cdigo de forma modular. Para utilizar en mdulo desarrollado por otro programado, por
ejemplo optica.py, lo nico que hay que hacer es llamarlo antes, import optica

2.11 Definicin de funciones

Seguidamente a las declaraciones de los mdulos se pueden escribir las funciones y clases que vayamos a utilizar.
Esto no significa que el programa vaya a realizar ninguna accin. En el siguiente tema se ver cmo hay que
desarrollar el cdigo para crear estas funciones y clases.
Una ventaja de Python es que en un mismo programa (o mdulo, segn definamos) podemos escribir muchas
funciones y clases a la vez, por lo que se simplifica la revisin de cdigo y su mantenimiento. Asimismo, incluir
varias funciones en un mismo archivo permite poder pasar nuestro cdigo a otros programadores de una forma
sencilla.
def f1(x = 3.3):
"""
* (float) --> (float)
* Descripcin: Funcin que devuelve el seno de un entero dado.
* Entradas:
- x = entero.
* Salidas:
- y = seno(entero)
* Test:
>>> print("f1(0.7)")
0.64421768723769102
"""
y = sp.sin(x)
return y

def f2(x=3):
"""
* (float) --> (float)
* Descripcin: Funcin que devuelve el seno de un entero dado.
* Entradas:
- x = entero.
* Salidas:
- y = cos(entero)
* Test:
>> print("f2(0.7)")
0.7648421872844885
"""
y = sp.cos(x)
return y

Python no utiliza parntesis o llaves para decir qu cdigo pertenece a una funcin. Es de esencial importancia
en Python seguir un sistema de indentacin. Es decir, el cdigo que est dentro de una funcin tiene que estr

2.11. Definicin de funciones 25


PIMCD2013-python, Publicacin 1.0

indentado dentro de la funcin como en el ejemplo anterior para que pertenezca a la funcin. Para salirnos de la
funcin, simplemente des-indentamos el cdigo.

2.12 Cdigo ejecutable: main

A una funcin de Python se la puede llamar de dos formas: a travs de otra funcin python o directamente. El
comportamiento de la funcin puede ser distinto por lo que se debe de tener cuidado. Si, por ejemplo, tenemos el
siguiente codigo al final del archivo:
if __name__ == __main__:

# Creamos el array x
x = sp.linspace(0,10,100)

# Calculamos el seno y el coseno mediante las funciones creadas.


y1 = f1(x)
y2 = f2(x)

# Dibujamos las dos funciones en una nica figura.


plt.figure()
plt.plot(x,y1,k, label=seno)
plt.hold(True)
plt.plot(x,y2,r, label=coseno)
plt.show()

Llegados a este punto podemos ver nuestra programa completo que no servir de plantilla para el resto de progra-
mas que creemos,
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_estructura_programa.py
# Propsito: Ejemplo de archivo con la estructura de un programa
#
# Origen: Propio
# Autor: Jos Mara Herrera-Fernandez y Luis Miguel Sanchez Brea
#
# Creacin: 12 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Archivo plantilla para generar programas en Python.

"""

import scipy
import scipy as sp
from scipy import *
from scipy import sin
from scipy.fftpack import fft
import matplotlib.pyplot as plt

26 Captulo 2. Puesta en Marcha


PIMCD2013-python, Publicacin 1.0

def f1(x = 3.3):


"""
* (float) --> (float)
* Descripcin: Funcin que devuelve el seno de un entero dado.
* Entradas:
- x = entero.
* Salidas:
- y = seno(entero)
* Test:
>>> print("f1(0.7)")
0.64421768723769102
"""
y = sp.sin(x)
return y

def f2(x=3):
"""
* (float) --> (float)
* Descripcin: Funcin que devuelve el seno de un entero dado.
* Entradas:
- x = entero.
* Salidas:
- y = cos(entero)
* Test:
>> print("f2(0.7)")
0.7648421872844885
"""
y = sp.cos(x)
return y

if __name__ == __main__:

# Creamos el array x
x = sp.linspace(0,10,100)

# Calculamos el seno y el coseno mediante las funciones creadas.


y1 = f1(x)
y2 = f2(x)

# Dibujamos las dos funciones en una nica figura.


plt.figure()
plt.plot(x,y1,k, label=seno)
plt.hold(True)
plt.plot(x,y2,r, label=coseno)
plt.show()

Ejecutando,

2.12. Cdigo ejecutable: main 27


PIMCD2013-python, Publicacin 1.0

1.0

0.5

0.0

0.5

1.00 2 4 6 8 10

2.13 Sistema de verificacin del cdigo

En el apartado de generacin de ayudas vimos que era conveniente aadir un apartado de verificacin de la la fun-
cin que llamamos Test. Sin embargo, en ocasiones las funciones son demasiado grades para aadir este apartado.
En estas ocasiones la solucin es simple, nos creamos otra funcin que invoque a la primera proporcionando datos
conocidos. De esta forma continuaremos probando el buen funcionamiento de nuestra funcin sin el inconveniente
del espacio.

28 Captulo 2. Puesta en Marcha


CAPTULO 3

Lenguajes de Programacin

Autores Jos Mara Herrera Fernndez, Luis Miguel Snchez Brea

Contenidos de este captulo:


Caractersticas de programacin
Elementos del lenguaje
Comentarios
Variables
Tipos de datos
Listas y Tuplas
Diccionarios
Conjuntos
Listas por comprensin
Funciones
Clases
Condicionales
Bucle for
Bucle while
Mdulos
Sistema de objetos

Existen numerosos manuales de programacin, adems de magnificos y extensos manuales oficiales. Sirva de
ejemplo, http://pyspanishdoc.sourceforge.net/tut/tut.html, una amplia gua en espaol que a pesar de ser escrita en
2005 nos proporcionar toda la informacn que necesitamos. Nosotros en esta seccin nos limitaremos a aportar
un resumen tomado de la wikipedia para que el lector pueda seguir el resto del libro de forma cmoda aunque
recomendamos visitar tanto la fuente original de la informacin, http://es.wikipedia.org/wiki/Python, como la gua
que acabamos de mencionar.

3.1 Caractersticas de programacin

No hace falta definir los datos.


Las funciones se almacenan en mdulos, que pueden ser del tamao que deseemos.
Es necesario declarar los modulos y las funciones de otros mdulos que se van a implementar.
Hay infinidad de mdulos de cualquier area de inters.

3.1.1 Elementos del lenguaje

Python fue diseado para ser ledo con facilidad. Una de sus caractersticas es el uso de palabras donde otros
lenguajes utilizaran smbolos. Por ejemplo, los operadores lgicos !, || y && en Python se escriben not, or y and,

29
PIMCD2013-python, Publicacin 1.0

respectivamente.
El contenido de los bloques de cdigo (bucles, funciones, clases, etc.) es delimitado mediante espacios o tabula-
dores, conocidos como indentacin, antes de cada lnea de rdenes pertenecientes al bloque. Python se diferencia
as de otros lenguajes de programacin que mantienen como costumbre declarar los bloques mediante un conjunto
de caracteres, normalmente entre llaves {}. Se pueden utilizar tanto espacios como tabuladores para identar el
cdigo, pero se recomienda no mezclarlos.
Debido al significado sintctico de la indentacin, una instruccin debe estar contenida en lnea. No obstante, si
por legibilidad se quiere dividir la instruccin en varias lneas, aadiendo una barra invertida al final de una lnea,
se indica que la instruccin contina en la siguiente.
lista = [valor 1,valor 2,valor 3]
cadena = Esto es una cadena bastante larga

que es equivalente a
lista = [valor 1,valor 2 \
,valor 3]
cadena = Esto es una cadena \
bastante larga

3.1.2 Comentarios

Los comentarios se pueden poner de dos formas. La primera y ms apropiada para comentarios largos es utilizando
la notacin comentario , tres apostrofes de apertura y tres de cierre.

Comentario ms largo en una lnea en Python

La segunda notacin utiliza el smbolo # delante de la lnea a comentar,


print "Hola mundo" # Tambin es posible aadir un comentario al final de una lnea de cdigo

El intrprete no tiene en cuenta los comentarios, lo cual es til si deseamos poner informacin adicional en nuestro
cdigo como, por ejemplo, una explicacin sobre el comportamiento de una seccin del programa.

3.1.3 Variables

Las variables se definen de forma dinmica, lo que significa que no se tiene que especificar cul es su tipo de
antemano y puede tomar distintos valores en otro momento, incluso de un tipo diferente al que tena previamente.
Se usa el smbolo = para asignar valores.
x = 1
x = "Esta variable es una cadena" # Esto es posible porque los tipos son asignados dinmicamente.

3.1.4 Tipos de datos

Los tipos de datos se pueden resumir en esta tabla:

30 Captulo 3. Lenguajes de Programacin


PIMCD2013-python, Publicacin 1.0

Tipo Clase Notas Ejemplo


str Cadena Inmutable Cadena
unicode Cadena Versin Unicode de str uCadena
list Secuencia Mutable, puede contener objetos de diversos [4.0, Cadena, True]
tipos
tuple Secuencia Inmutable, puede contener objetos de diversos (4.0, Cadena, True)
tipos
set Conjunto Mutable, sin orden, no contiene duplicados set([4.0, Cadena, True])
frozen- Conjunto Inmutable, sin orden, no contiene duplicados frozenset([4.0, Cadena,
set True])
dict Mapping Grupo de pares clave:valor {key1: 1.0, key2: False}
int Nmero entero Precisin fija, convertido en long en caso de 42
overflow.
long Nmero entero Precisin arbitraria 42L
456966786151987643L
float Nmero Coma flotante de doble precisin 3.1415927
decimal
com- Nmero Parte real y parte imaginaria j. (4.5 + 3j)
plex complejo
bool Booleano Valor booleano verdadero o falso True o False
Mutable: si su contenido (o dicho valor) puede cambiarse en tiempo de ejecucin.
Inmutable: si su contenido (o dicho valor) no puede cambiarse en tiempo de ejecucin.

3.1.5 Listas y Tuplas

Para declarar una lista se usan los corchetes [ ], en cambio, para declarar una tupla se usan los parntesis (
). En ambas los elementos se separan por comas, y en el caso de las tuplas es necesario que tengan como
mnimo una coma.
Tanto las listas como las tuplas pueden contener elementos de diferentes tipos. No obstante las listas suelen
usarse para elementos del mismo tipo en cantidad variable mientras que las tuplas se reservan para elementos
distintos en cantidad fija.
Para acceder a los elementos de una lista o tupla se utiliza un ndice entero (empezando por 0, no por 1).
Se pueden utilizar ndices negativos para acceder elementos a partir del final, por ejemplo para acceder al
ltimo ndice deberamos de usar -1.
Las listas se caracterizan por ser mutables, es decir, se puede cambiar su contenido en tiempo de ejecucin,
mientras que las tuplas son inmutables ya que no es posible modificar el contenido una vez creada.
Listas
>>> lista = ["abc", 42, 3.1415] # Definicin de una lista con elementos de distinto tipo.
>>> lista[0] # Acceder a un elemento por su ndice, en este caso al primero.
abc
>>> lista[-1] # Acceder a un elemento usando un ndice negativo, en este caso el ltimo.
3.1415
>>> lista.append(True) # Aadir un elemento al final de la lista.
>>> lista
[abc, 42, 3.1415, True]
>>> del lista[3] # Borra un elemento de la lista usando un ndice (en este caso: True).
>>> lista
[abc, 42, 3.1415]
>>> lista[0] = "xyz" # Re-asignar el valor del primer elemento de la lista.
>>> lista
[xyz, 42, 3.1415]
>>> lista[0:2] # Mostrar los elementos de la lista del ndice "0" al "2" (sin incluir este ltimo)
[xyz, 42]
>>> lista_anidada = [lista, [True, 42L]] # Es posible anidar listas
>>> lista_anidada

3.1. Caractersticas de programacin 31


PIMCD2013-python, Publicacin 1.0

[[xyz, 42, 3.1415], [True, 42L]]


>>> lista_anidada[1][0] # Acceder a un elemento de una lista dentro de otra lista (del segundo ele
True

Tuplas
>>> tupla = ("abc", 42, 3.1415) # Definicin de una tupla con elementos de distinto tipo.
>>> tupla[0] # Acceder a un elemento por su ndice en este caso al primero.
abc
>>> del tupla[0] # No es posible borrar (ni aadir) un elemento en una tupla, lo que provocar una
( Excepcin )
# Tampoco es posible re-asignar el valor de un elemento en una tupla, lo que tambin provocar una
>>> tupla[0] = "xyz"
( Excepcin )
>>> tupla[0:2] # Mostrar los elementos de la tupla del ndice "0" al "2" (sin incluir este ltimo)
(abc, 42)
>>> tupla_anidada = (tupla, (True, 3.1415)) # Tambin es posible anidar tuplas.
>>> 1, 2, 3, "abc" # Esto tambin es una tupla, aunque es recomendable ponerla entre parntesis (
(1, 2, 3, abc)
>>> (1) # Aunque entre parntesis, esto no es una tupla, ya que no posee al menos una coma, por lo
1
>>> (1,) # En cambio, en este otro caso, s es una tupla.
(1,)
>>> (1, 2) # Con ms de un elemento no es necesaria la coma final.
(1, 2)
>>> (1, 2,) # Aunque agregarla no modifica el resultado.
(1, 2)

3.1.6 Diccionarios

Para declarar un diccionario se usan las llaves { }. Contienen elementos separados por comas, donde cada
elemento est formado por un par clave : valor (el smbolo : separa la clave de su valor correspondiente).
Los diccionarios son mutables, es decir, se puede cambiar el contenido de un valor en tiempo de ejecucin.
En cambio, las claves de un diccionario deben ser inmutables. Esto quiere decir, por ejemplo, que no podre-
mos usar ni listas ni diccionarios como claves.
El valor asociado a una clave puede ser de cualquier tipo de dato, incluso un diccionario.
>>> diccionario = {"cadena": "abc", "numero": 42, "lista": [True, 42L]} # Diccionario que tiene di
>>> diccionario["cadena"] # Usando una clave, se accede a su valor.
abc
>>> diccionario["lista"][0] # Acceder a un elemento de una lista dentro de un valor (del valor de
True
>>> diccionario["cadena"] = "xyz" # Re-asignar el valor de una clave.
>>> diccionario["cadena"]
xyz
>>> diccionario["decimal"] = 3.1415927 # Insertar un nuevo elemento clave:valor.
>>> diccionario["decimal"]
3.1415927
>>> diccionario_mixto = {"tupla": (True, 3.1415), "diccionario": diccionario} # Tambin es posible
>>> diccionario_mixto["diccionario"]["lista"][1] # Acceder a un elemento dentro de una lista, que
42L
>>> diccionario = {("abc",): 42} # S es posible que una clave sea una tupla, pues es inmutable.
>>> diccionario = {["abc"]: 42} # No es posible que una clave sea una lista, pues es mutable, lo
( Excepcin )

32 Captulo 3. Lenguajes de Programacin


PIMCD2013-python, Publicacin 1.0

3.1.7 Conjuntos

Los conjuntos se construyen mediante set(items) donde items es cualquier objeto iterable, como listas o
tuplas. Los conjuntos no mantienen el orden ni contienen elementos duplicados.
Se suelen utilizar para eliminar duplicados de una secuencia, o para operaciones matemticas como inter-
seccin, unin, diferencia y diferencia simtrica.
>>> conjunto_inmutable = frozenset(["a", "b", "a"]) # Se utiliza una lista como objeto iterable.
>>> conjunto_inmutable
frozenset([a, b])
>>> conjunto1 = set(["a", "b", "a"]) # Primer conjunto mutable.
>>> conjunto1
set([a, b])
>>> conjunto2 = set(["a", "b", "c", "d"]) # Segundo conjunto mutable.
>>> conjunto2
set([a, c, b, d]) # Recuerda, no mantienen el orden, como los diccionarios.
>>> conjunto1 & conjunto2 # Interseccin
set([a, b])
>>> conjunto1 | conjunto2 # Unin.
set([a, c, b, d])
>>> conjunto1 - conjunto2 # Diferencia (1).
set([])
>>> conjunto2 - conjunto1 # Diferencia (2).
set([c, d])
>>> conjunto1 ^ conjunto2 # Diferencia simtrica.
set([c, d])

3.1.8 Listas por comprensin

Una lista por comprensin (en ingls: list comprehension) es una expresin compacta para definir listas. Al igual
que lambda, aparece en lenguajes funcionales. Ejemplos:
>>> range(5) # La funcin "range" devuelve una lista, empezando en 0 y terminando con el nmero in
[0, 1, 2, 3, 4]
>>> [i*i for i in range(5)] # Por cada elemento del rango, lo multiplica por s mismo y lo agrega
[0, 1, 4, 9, 16]
>>> lista = [(i, i + 2) for i in range(5)].
>>> lista
[(0, 2), (1, 3), (2, 4), (3, 5), (4, 6)]

3.1.9 Funciones

Las funciones se definen con la palabra clave def, seguida del nombre de la funcin y sus argumentos entre
parntesis para finalizar con :, es decir,
>>> def mi_funcion(arg1, arg2,..., argN):

Otra forma de escribir funciones, aunque menos utilizada, es con la palabra clave lambda. lambda es un
cosntructor que sirver para ejecutar funciones annimas, es decir funciones sin ningn nombre pero que
crean una referencia a un objeto funcin. La sintaxis de lambda en python es
lambda <aParameterList> : <a Python expression using the parameters>

El valor devuelto en las funciones con def ser el dado con la instruccin return. lambda no necesita de re-
turn para retornar un valor, ya que est implcito, puesto que la funcin entera debe ser una nica expresin.
def

3.1. Caractersticas de programacin 33


PIMCD2013-python, Publicacin 1.0

>>> def suma(x, y = 2):


... return x + y # Devuelve la suma del valor de la variable "x" y el valor de "y".
...
>>> suma(4) # La variable "y" no se modifica, siendo su valor: 2
6
>>> suma(4, 10) # La variable "y" s se modifica, siendo su nuevo valor: 10
14

lambda
>>> suma = lambda x, y = 2: x + y
>>> suma(4) # La variable "y" no se modifica, siendo su valor: 2
6
>>> suma(4, 10) # La variable "y" s se modifica, siendo su nuevo valor: 10
14

3.1.10 Clases

Las clases se definen con la palabra clave class, seguida del nombre de la clase y, si hereda de otra clase, el
nombre de esta.
En Python 2.x es recomendable que una clase herede de object, en Python 3.x esto ya no har falta.
En una clase un mtodo equivale a una funcin, y una propiedad equivale a una variable.
__init__ es un mtodo especial que se ejecuta al instanciar la clase, se usa generalmente para inicializar
propiedades y ejecutar mtodos necesarios. Al igual que todos los mtodos en Python, debe tener al menos
un parmetro, generalmente se utiliza self. El resto de parmetros sern los que se indiquen al instanciar la
clase.
Las propiedades que se desee que sean accesibles desde fuera de la clase se deben declarar usando self.
delante del nombre.
En python no existe el concepto de encapsulacin, por lo que el programador debe ser responsable de asignar
los valores a las propiedades
>>> class Persona(object):
... def __init__(self, nombre, edad):
... self.nombre = nombre # Una Propiedad cualquiera.
... self.edad = edad # Otra propiedad cualquiera.
... def mostrar_edad(self): # Es necesario que, al menos, tenga un parmetro, generalmente: "s
... print self.edad # mostrando una propiedad.
... def modificar_edad(self, edad): # Modificando Edad.
... if edad < 0 or edad > 150: # Se comprueba que la edad no sea menor de 0 (algo imposibl
... return False
... else: # Si est en el rango 0-150, entonces se modifica la variable.
... self.edad = edad # Se modifica la edad.
...
>>> p = Persona("Alicia", 20) # Instanciamos la clase, como se puede ver, no se especifica el valo
>>> p.nombre # La variable "nombre" del objeto s es accesible desde fuera.
Alicia
>>> p.nombre = "Andrea" # Y por tanto, se puede cambiar su contenido.
>>> p.nombre
Andrea
>>> p.mostrar_edad() # Podemos llamar a un mtodo de la clase.
20
>>> p.modificar_edad(21) # Y podemos cambiar la edad usando el mtodo especfico que hemos hecho p
>>> p.mostrar_edad()
21

34 Captulo 3. Lenguajes de Programacin


PIMCD2013-python, Publicacin 1.0

3.1.11 Condicionales

Una sentencia condicional if ejecuta su bloque de cdigo interno slo si se cumple cierta condicin. Se define
usando la palabra clave if seguida de la condicin, y el bloque de cdigo. Condiciones adicionales, si las hay, se
introducen usando elif seguida de la condicin y su bloque de cdigo. Todas las condiciones se evalan secuen-
cialmente hasta encontrar la primera que sea verdadera, y su bloque de cdigo asociado es el nico que se ejecuta.
Opcionalmente, puede haber un bloque final (la palabra clave else seguida de un bloque de cdigo) que se ejecuta
slo cuando todas las condiciones resultan falsas.
>>> verdadero = True
>>> if verdadero: # No es necesario poner "verdadero == True".
... print "Verdadero"
... else:
... print "Falso"
...
Verdadero
>>> lenguaje = "Python"
>>> if lenguaje == "C": # lenguaje no es "C", por lo que este bloque se obviar y evaluar la sigu
... print "Lenguaje de programacin: C"
... elif lenguaje == "Python": # Se pueden aadir tantos bloques "elif" como se quiera.
... print "Lenguaje de programacin: Python"
... else: # En caso de que ninguna de las anteriores condiciones fuera cierta, se ejecutara este
... print "Lenguaje de programacin: indefinido"
...
Lenguaje de programacin: Python
>>> if verdadero and lenguaje == "Python": # Uso de "and" para comprobar que ambas condiciones son
... print "Verdadero y Lenguaje de programacin: Python"
...
Verdadero y Lenguaje de programacin: Python

3.1.12 Bucle for

El bucle for es similar a foreach en otros lenguajes. Recorre un objeto iterable, como una lista, una tupla o un
generador, y por cada elemento del iterable ejecuta el bloque de cdigo interno. Se define con la palabra clave for
seguida de un nombre de variable, seguido de in, seguido del iterable, y finalmente el bloque de cdigo interno.
En cada iteracin, el elemento siguiente del iterable se asigna al nombre de variable especificado:
>>> lista = ["a", "b", "c"]
>>> for i in lista: # Iteramos sobre una lista, que es iterable.
... print i
...
a
b
c
>>> cadena = "abcdef"
>>> for i in cadena: # Iteramos sobre una cadena, que tambin es iterable.
... print i, # Aadiendo una coma al final hacemos que no introduzca un salto de lnea, sino u
...
a b c d e f

3.1.13 Bucle while

El bucle while evala una condicin y, si es verdadera, ejecuta el bloque de cdigo interno. Contina evaluando y
ejecutando mientras la condicin sea verdadera. Se define con la palabra clave while seguida de la condicin, y a
continuacin el bloque de cdigo interno:
>>> numero = 0
>>> while numero < 10:
... numero += 1
... print numero,

3.1. Caractersticas de programacin 35


PIMCD2013-python, Publicacin 1.0

...
1 2 3 4 5 6 7 8 9

3.1.14 Mdulos

Existen muchas propiedades que se pueden agregar al lenguaje importando mdulos, que son minicdigos (la
mayora escritos tambin en Python) que proveen de ciertas funciones y clases para realizar determinadas tareas.
Un ejemplo es el mdulo Tkinter, que permite crear interfaces grficas basadas en la biblioteca Tk. Otro ejemplo es
el mdulo os, que provee acceso a muchas funciones del sistema operativo. Los mdulos se agregan a los cdigos
escribiendo import seguida del nombre del mdulo que queramos usar.
>>> import os # Mdulo que provee funciones del sistema operativo
>>> os.name # Devuelve el nombre del sistema operativo
posix
>>> os.mkdir("/tmp/ejemplo") # Crea un directorio en la ruta especificada
>>> import time # Mdulo para trabajar con fechas y horas
>>> time.strftime("%Y-%m-%d %H:%M:%S") # Dndole un cierto formato, devuelve la fecha y/o hora ac
2010-08-10 18:01:17

NOTA: En http://pyspanishdoc.sourceforge.net/modindex.html podemos encontrar el ndice de mdulos estndar


de python.

3.1.15 Sistema de objetos

En Python todo es un objeto (incluso las clases). Las clases, al ser objetos, son instancias de una metaclase. Python
adems soporta herencia mltiple y polimorfismo.
>>> cadena = "abc" # Una cadena es un objeto de "str"
>>> cadena.upper() # Al ser un objeto, posee sus propios mtodos
ABC
>>> lista = [True, 3.1415] # Una lista es un objeto de "list"
>>> lista.append(42L) # Una lista tambin (al igual que todo) es un objeto, y tambin posee sus pr
>>> lista
[True, 3.1415, 42L]

36 Captulo 3. Lenguajes de Programacin


CAPTULO 4

Mdulos Cientficos

Con los mdulos generales, Phyton es dificilmente aplicable al entorno cientfico. Afortunadamente la comunidad
de desarrolladores pronto puso solucin a este inconveniente mediante la creacin de potentes mdulos de clculo
numrico. Hoy da existen mdulos especficos de casi todas las reas cientifico-ingenieriles. En este tema presen-
taremos brevemente algunos de los mdulos ms utilizados y explicaremos diversos ejemplos que nos ayudaran a
aprender su utilizacin de forma rpida e intuitiva.
.

4.1 Numpy

Autores Jos Mara Herrera Fernndez, Luis Miguel Snchez Brea

Contenidos de este captulo:


Carga de un archivo de datos
Arrays
Matrices
Operaciones y funciones

Uno de los mdulos ms importantes de Python es Numpy. El origen de Numpy se debe principalmente al dise-
ador de software Jim Hugunin quien dise el mdulo Numeric para dotar a Python de capacidades de clculo
similares a las de otros softwares como MATLAB. Posteriormente, mejor Numeric incorporando nuevas funcio-
nalidades naciendo lo que hoy conocemos como Numpy.
Numpy es el encargado de aadir toda la capacidad matemtica y vectorial a Python haciendo posible operar
con cualquier dato numrico o array (posteriormente veremos qu es un array). Incorpora operaciones tan bsicas
como la suma o la multiplicacin u otras mucho ms complejas como la transformada de Fourier o el lgebra lineal.
Adems incorpora herramientas que nos permiten incorporar cdigo fuente de otros lenguajes de programacin
como C/C++ o Fortran lo que incrementa notablemente su compatibilidad e implementacin.
Para poder utilizar este mdulo sino hemos instalado python(x,y) lo primero que debemos de hacer es descargarnos
la ltima versin desde el sitio oficial http://www.scipy.org/Download. En caso de que nuestro sistema operativo
sea Linux probablemente venga instalado dentro de Python. De no ser as debemos instalarlo por el mtodo
habitual. Para ms informacin y otros sistemas operativos consultar las notas oficiales de instalacin. Para cargar
el mdulo en Python y poder llamarlo de formar ms cmoda es de uso extendido la utilizacin del alias np,
import numpy as np

4.1.1 Carga de un archivo de datos

En el mbito cientfico es frecuente almacenar y trasladar paquetes de datos en archivos escritos en, por ejemplo,
cdigo ASCII. Python incorpora varias funciones que nos permiten la lectura y escritura en estos archivos facili-

37
PIMCD2013-python, Publicacin 1.0

tando su manejo. Un ejemplo de ello es el comando loadtxt que nos permite cargar los datos contenidos en un
archivo de texto o dat.
Ejemplo 4.1
>>> import numpy as np # Importamos numpy como el alias np
# Cargamos los datos de archivo.txt en datos. En este caso el delimitador es la coma.
>>> datos = numpy.loadtxt(C:\ruta\a\tu\archivo.txt, delimiter = ,)

Ejemplo 4.2
>>> import numpy as np # Importamos numpy como el alias np.
>>> archivoDatos = np.loadtxt(codigo\archivoDatos.dat)
>>> print (archivoDatos) # Presentamos en pantalla los datos cargados.

Ejemplo 4.3
>>> from StringIO import StringIO # StringIO se comporta como un archivo objeto.
>>> c = StringIO("0 1\n2 3")
>>> np.loadtxt(c)
array([[ 0., 1.],
[ 2., 3.]])

4.1.2 Arrays

Con toda probabilidad, el lector que haya realizado un acercamiento a cualquier lenguaje de programacin habr
odo hablar de arrays. Un array es el termino que traslada el concepto matemtico de vector o matriz a la progra-
macin aadindole la nocin de almacenamiento en memoria. Los arrays disponen en su interior de una serie de
elementos dispuestos en filas y/o columnas dependiendo de la dimensin.
El desarrollo y la principal finalidad del mdulo Numpy es la creacin y modificacin de arrays multidimensio-
nales. Para este fin utilizaremos las clase ndarray del ingles N-dimensional array o usando su alias simplemente
array (no confundir con la clase array.array que ofrece menos funcionalidad). En Python cada clase puede tener
atributos que se pueden llamar con el mtodo visto anteriormente o simplemente escribiendo a continuacin de
la clase un punto y el atributo. En la mayora de los IDEs al cargar la clase y escribir el punto aparecen todos los
atributos disponibles en orden alfabtico por lo que en caso de dudar siempre podemos utilizar este mtodo para
escribir el comando. En el caso de ndarray los principales atributos son los siguientes:
ndarray.ndim > Proporciona el nmero de dimensiones de nuestro array. El array identidad es un array
cuadrado con una diagonal principal unitaria.
ndarray.shape > Devuelve la dimensin del array, es decir, una tupla de enteros indicando el tamao del
array en cada dimensin. Para una matriz de n filas y m columnas obtendremos (n,m).
ndarray.size > Es el nmero total de elementos del array.
ndarray.dtype > Es un objeto que describe el tipo de elementos del array.
ndarray.itemsize > devuelve el tamao del array en bytes.
ndarray.data > El buffer contiene los elementos actuales del array.
Veamos un ejemplo de su uso con un array sencillo de diez elementos,
Ejemplo 4.4
>>> import numpy as np # Importamos numpy como el alias np
>>> miArray = np.arange(10) # Creamos un array de 0 a 9 separados de uno en uno
>>> miArray # Presentamos en pantalla el array creado
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> type(miArray) #Comprobamos que es un ndarray
<type numpy.ndarray>
>>> miArray.ndim # Consultamos el nmero de dimensiones
1
>>> miArray.shape # Consultamos la dimensin

38 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

(10,)
>>> miArray.size # Consultamos la dimensin
10
>>> miArray.dtype # Consultamos el tipo de elementos del array
dtype(int64)
>>> miArray.itemsize # tamao en bytes
8
>>> miArray.data # Consultamos el buffer de memoria.
<read-write buffer for 0x2fb57a0, size 80, offset 0 at 0x2f664b0>

Como hemos mencionando anteriormente, los arrays son unos de los elementos ms utilizados por los progra-
madores bajo cualquier lenguaje. Este gran uso hace que dispongamos de una gran variedad de comandos para
la creacin de arrays: arrays unidimensionales, multidimensionales, nulos, unitarios, secuenciales, de nmeros
aleatorios, etc. Dependiendo de las necesidades de nuestro problema escogeremos la opcin ms adecuada.
identity(n,dtype). Devuelve la matriz identidad, es decir, uma matriz cuadrada nula excepto en su diagonal
principal que es unitaria. n es el nmero de filas (y columnas) que tendr la matriz y dtype es el tipo de dato.
Este argumento es opcional. Si no se establece, se toma por defecto como flotante.
ones(shape,dtype). Crea un array de unos compuesto de shape elementos.
zeros(shape, dtype). Crea un array de ceros compuesto de shape elementos.
empty(shape, dtype). Crea un array de ceros compuesto de shape elementos sin entradas.
eye(N, M, k, dtype). Crea un array bidimensional con unos en la diagonal k y ceros en el resto. Es similar
a identity. Todos los argumentos son opcionales. N es el nmero de filas, M el de columnas y k es el ndice
de la diagonal. Cuando k=0 nos referimos a la diagonal principal y por tanto eye es similar a identity.
arange([start,]stop[,step,],dtype=None). Crea un array con valores distanciados step entre el valor inicial
star y el valor final stop. Si no se establece step python establecer uno por defecto.
linspace(start,stop,num,endpoint=True,retstep=False). Crea un array con valor inicial start, valor final
stop y num elementos.
meshgrid(x,y). Genera una matriz de coordenadas a partir de dos los arrays x, y.
En el siguiente ejemplo podemos ver su utilizacin,
Ejemplo 4.5
>>> from numpy import * # Importamos todo el mdulo numpy.
>>> zeros( (3,4) ) # Creamos un array nulo de 3 filas y 4 columnas.
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>> ones(9) # Creamos un array unitario de 1 fila y 9 columnas,
array([ 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> empty( (2,3) ) # Creamos un array sin entradas de 2x3.
array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
[ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])
>>> arange( 10, 30, 5 ) # Creamos un array con inicio en 10 final en 30 y paso de 5.
array([10, 15, 20, 25])
>>> linspace( 0, 2, 9 ) # Array de 9 elementos de 0 a 2
array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])
>>> x = linspace( 0, 2*pi, 100 ) # Para grficas conviene tener muchos puntos, en este caso 100
>>> X, Y = np.meshgrid([1,2,3], [4,5,6,7]) # Generamos una matriz de coordenadas.
>>> X
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
>>> Y
array([[4, 4, 4],
[5, 5, 5],

4.1. Numpy 39
PIMCD2013-python, Publicacin 1.0

[6, 6, 6],
[7, 7, 7]])

4.1.3 Matrices

Un subtipo especial de array bidimensional de NumPy es la matriz. Una matriz es como una array, excepto que la
multiplicacin de matrices (y exponenciacin) reemplaza la multiplicacin elemento a elemento. Las matrices se
crean mediante la funcin matrix.
Ejemplo 4.6
>>> from numpy import matrix # Importamos matrix del mdulo numpy.
>>> a = matrix([[1,3,-5],[3,4,2],[-5,2,0]])
matrix([[ 1, 3, -5],
[ 3, 4, 2],
[-5, 2, 0]])
>>> b = matrix([[1],[5],[3]])
>>> b
matrix([[1],
[5],
[3]])
>>> a*b
matrix([[ 1],
[29],
[ 5]])

Definidas las matrices, podemos hacer uso de todas las funciones relacionadas con el lgebra lineal como la
transposicin, la diagonalizacin etc.
Ejemplo 4.7
>>> b.T # Calculamos la transpuesta de *b*.
matrix([[1, 5, 3]])
>>> b.H # Calculamos la hermtica (transpuesta y conjugada) de *b*.
matrix([[1, 5, 3]])
>>> c = a.I # Calculamos la inversa de *b*.
>>> c
matrix([[ 0.02439024, 0.06097561, -0.15853659],
[ 0.06097561, 0.15243902, 0.10365854],
[-0.15853659, 0.10365854, 0.0304878 ]])
>>> a*c # Multiplicamos las matrices *a* y *c*.
matrix([[ 1.00000000e+00, -5.55111512e-17, -6.93889390e-18],
[ 0.00000000e+00, 1.00000000e+00, 4.16333634e-17],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])

Con el paquete linalg podemos calcular el determinante (det), resolver ecuaciones lineales (solve) y calcular auto-
valores y autovectores.
Ejemplo 4.8
>>> linalg.det(a) # Clculo del determinante.
-164.0
>>> d = linalg.solve(a,b) # Resolucin de ecuaciones lineales.
>>> d
matrix([[-0.14634146],
[ 1.13414634],
[ 0.45121951]])
>>> a*d
matrix([[ 1.],
[ 5.],
[ 3.]])
>>> e = linalg.eig(a) # Clculo de autovalores y autovectores.
>>> e[0]

40 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

array([-5.78304165, 6.23396835, 4.5490733 ])


>>> e[1]
matrix([[ 0.65072855, -0.7001856 , -0.29375583],
[-0.33849942, -0.61380708, 0.71320335],
[ 0.67968412, 0.3646656 , 0.6364342 ]])
>>> u = e[1]
>>> u.T*a*u
matrix([[ -5.78304165e+00, -1.22688318e-15, -7.92985469e-16],
[ -1.62554432e-15, 6.23396835e+00, 1.43223107e-15],
[ -7.68916181e-16, 1.83533744e-15, 4.54907330e+00]])

La funcin eig devuelve una tupla donde el primer elemento es un array de autovalores y el segundo es una matriz
que contiene a los autovectores.

4.1.4 Operaciones y funciones

El mdulo numpy contiene todas las operaciones usuales entre arrays como las matemticas (suma, resta, multi-
plicacin, etc), las lgicas (and, or, xor, etc), binarias, ... Lo ms fcil y sencillo es en caso de duda consultar la
documentacin oficial. De particular inters en ptica es la transformada de Fourier,
Ejemplo 4.9
>>> import numpy as np # Importamos numpy como el alias np.
>>> x=np.linspace(0,1,16)
>>> y=np.sin(x)
>>> print np.fft.fft(y)
array([ 6.82834723+0.j , -0.72886897+1.98380961j,
-0.46469805+0.9337634j , -0.42166285+0.57663662j,
-0.40711196+0.38478538j, -0.40066563+0.25695308j,
-0.39747563+0.15924205j, -0.39594637+0.07645992j,
-0.39548834+0.j , -0.39594637-0.07645992j,
-0.39747563-0.15924205j, -0.40066563-0.25695308j,
-0.40711196-0.38478538j, -0.42166285-0.57663662j,
-0.46469805-0.9337634j , -0.72886897-1.98380961j])

obsrvese como se ha formado en nmero complejo 2j. En python los nmeros complejos se forman (parte real
signo jparte imaginaria), es decir, separando parte real e imaginaria y sin ningn signo multiplicativo entre el
coeficiente y el numero imaginario j.
Ejemplo 4.10
>>> numero_complejo = (1 + 1j) # Defino el nmero complejo.
>>> print(numero_complejo) # Lo presento en pantalla.
(1+1j)
>>> type(numero_complejo) # Compruebo el tipo.
complex

4.2 Scipy

Autores Jos Mara Herrera Fernndez, Luis Miguel Snchez Brea

4.2. Scipy 41
PIMCD2013-python, Publicacin 1.0

Contenidos de este captulo:


Ejemplo: Encontrar mnimos de Intensidad de la difraccin provocada por una rendija.
Ejemplo: Encontrar mnimos en un intervalo definido.
Ejemplo: Ajuste de una funcin.
Ejemplo: Funcin de Bessel de orden cero y uno.
Ejemplo: Clculo de integrales
Ejemplo: Interpolacin
Ejemplo: Clculo de las raices de un polinomio

Scipy es una librera de herramientas numricas para Python que se distribuye libremente. El mdulo scipy con-
fiere al lenguaje general Python capacidades de clculo numrico de gran capacidad. Scipy adems de poseer en
su ncleo a Numpy, posee mdulos para optimizacin de funciones, integracin, funciones especiales, resolucin
de ecuaciones diferenciales ordinarias y otros muchos aspectos.

Figura 4.1: Figura 1. Scipy.

Su organizacin se estructura en subpaquetes, que se pueden considerar especializados en dominios cientficos


determinados. Podemos encontrar estos paquetes, segn la ayuda de scipy:
linalg Algebra lineal
signal Procesamiento de seales
stats Funciones estadsticas
special Funciones especiales
integrate Integracin
interpolate Herramientas de interpolacin
optimize Herramientas de optimizacin
fftpack Algortimos de transformada de Fourier
io Entrada y salida de datos
lib.lapack Wrappers a la librera LAPACK
lib.blas Wrappers a la librera BLAS
lib Wrappers a libreras externas
sparse Matrices sparse
misc otras utilidades
cluster Vector Quantization / Kmeans

42 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

maxentropy Ajuste a modelos con mxima entropa


Los subpaquetes de Scipy se tienen que importar de forma separada. Por ejemplo:
>>> from scipy import linalg, optimize.

Tanto Scipy como Numpy tienen versiones de su documentacin en pdf y html en http://docs.scipy.org/. Tambin
se puede obtener ayuda de las funciones y de los mdulos mediante
>>> sp.info(funcion)

como por ejemplo


>>> import scipy as sp # Importamos el mdulo scipy como el alias sp
>>> sp.info(sp.optimize.fmin) # Consultamos la informacin de la funcin fmin.

fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None,


full_output=0, disp=1, retall=0, callback=None)

Minimize a function using the downhill simplex algorithm.

Parameters
----------
func : callable func(x,*args)
The objective function to be minimized.
x0 : ndarray
Initial guess.
args : tuple
Extra arguments passed to func, i.e. f(x,*args).
callback : callable
Called after each iteration, as callback(xk), where xk is the
current parameter vector.

Returns
-------
xopt : ndarray
Parameter that minimizes function.
fopt : float
Value of function at minimum: fopt = func(xopt).
iter : int
Number of iterations performed.
funcalls : int
Number of function calls made.
warnflag : int
1 : Maximum number of function evaluations made.
2 : Maximum number of iterations reached.
allvecs : list
Solution at each iteration.

Other parameters
----------------
xtol : float
Relative error in xopt acceptable for convergence.
ftol : number
Relative error in func(xopt) acceptable for convergence.
maxiter : int
Maximum number of iterations to perform.
maxfun : number
Maximum number of function evaluations to make.
full_output : bool
Set to True if fopt and warnflag outputs are desired.
disp : bool
Set to True to print convergence messages.
retall : bool

4.2. Scipy 43
PIMCD2013-python, Publicacin 1.0

Set to True to return list of solutions at each iteration.

Notes
-----
Uses a Nelder-Mead simplex algorithm to find the minimum of function of
one or more variables.

Otra forma de buscar informacin es con el comando source, que lista el cdigo de esa funcin,
>>> sp.source(sp.linspace)

En scipy las funciones universales (suma, resta, division, etc.) se han alterado para no producir errores de coma
flotante cuando se encuentran errores; por ejemplo se devuelve NaN e Inf en los arrays en lugar de errores. Para
ayudar a la deteccin de estos eventos, hay disponibles varias funciones como sp.isnan, sp.isinfinite, sp.isinf.
Adems se han modificado algunas funciones (log, sqrt, funciones trigonometricas inversas) para devolver valores
complejos en lugar de NaN (por ejemplo sp.sqrt(-1) devuelve 1j).
Dada la gran cantidad de mdulos contenidos en Scipy, en esta seccin nos limitaremos en dar ejemplos de algunos
de ellos recordando que el camino ideal para el aprendizaje es la lectura de los manuales oficiales.

4.2.1 Ejemplo: Encontrar mnimos de Intensidad de la difraccin provocada por


una rendija.

Desde la educacin secundara uno de los problemas matemticos ms comunes es el de encontrar el mnimo de
una funcin. Si la funcin es simple no necesitamos python para encontrar las posibles soluciones, sin embargo,
si la funcin es compleja o simplemente queremos automatizar el calculo la respuesta es fmin el cual se encuentra
en scipy.optimize. En nuestro caso vamos a tratar de encontrar algn mnimo de intensidad de la diffraccin que
resulta a la salida de una rendija. Esta intensidad viene dada por la funcin sinc, (ecuacin (4.1)).

( ())
= 0 (4.1)
()/

donde a es el ancho de la rendija, x es el ngulo y es la longitud de onda. Como nos proponemos mantener
nuestro programa, lo primero que vamos a hacer es escribir la autoejecucin, la cabecera y la descripcin de
nuestro programa tal y como aprendimos en el tema anterior.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_uso_fmin.py
# Propsito: Aprender el uso de fmin para minimizar funciones
#
# Origen: Propio
# Autor: Jos Mara Herrera-Fernandez
#
# Creacin: 17 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Ejemplo de cmo usar la funcin fmin perteneciente a scipy.optimize para
encontrar el mnimo de una funcin.
"""

A continuacin cargaremos los mdulos que vamos a necesitar,

44 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

from scipy.optimize import fmin # Importamos fmin de scipy.optimize


from scipy import sin, pi, linspace # Importamos la funcion seno y el valor pi.

Definimos el sistema fsico de unidades y la funcin sinc(x) en python. Para ello recurrimos al comando def para
indicar que vamos a definir una funcin, el nombre que le vamos a dar a nuestra funcin que en este caso es sinc
y por ltimo los argumentos de nuestra funcin. Para nuestro ejemplo con un nico argumento nos valdr, (x),
# Definimos el sistema fsico de unidades
um = 1 # micras
mm = 100 * um # milmetros

# Definimos los parmetros fsicos


anchura_rendija = 40 * um
longitud_onda = 0.630 * um

# Definimos la funcin "calcular_minimo_funcion".


def sinc (x):
"""
* (float) --> (float)
* Descripcin: Funcin sinc de un nmero dado (sen(x)/x).
* Entradas:
- x = float.
* Salidas:
- funcion_sinc = seno(float) / float
* Test:
>>> print(sinc(5))
3.46751168769e-06
"""
# Definimos la funcin sinc normalizada.
funcion_sinc = (sin(pi*anchura_rendija*sin(x)/longitud_onda)/(pi*anchura_rendija*sin(x)/longitud
return funcion_sinc # La devolvemos.

la funcin fmin necesita de valores iniciales a modo de semilla para comenzar las iteraciones. En nuestro caso
hemos elegido como valor 0.001,
# fmin necesita una semilla as que se la proporcionamos.
semilla = 0.001

calculamos el valor del mnimo mediante fmin,


# Calculamos el valor mnimo.
x_minimo_intensidad = fmin(sinc,semilla)

y por ltimo presentamos en pantalla el resultado mediante un print. Como podemos observar, tomamos direc-
tamente el valor calculado para el print. Esto lo conseguimos gracias al simbolo %. La utilizacin es sencilla, en
el lugar donde queramos que aparezca el valor de nuestra variable escribimos el smbolo % seguido del nmero
de digitos que queramos que tenga la parte real y por ltipo el tipo de numero que queremos mostrar. En nuestro
caso %1.2f significa un digito real, dos decimales y el tipo float. Adems fuera de las comillas del print debemos
de poner otro % y entre parntesis la variable a la que llamamos (en nuestro caso x_minimo_intensidad y sinc
(x_minimo_intensidad) ).
# Presenta en pantalla el mnimo y el valor de la funcin en ese punto.
print (El valor de x en el que se encuentra el mnimo es %1.2f que se corresponde con y = %1.2f
% (x_minimo_intensidad , sinc (x_minimo_intensidad )))

Ejecutando,
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 14
Function evaluations: 28
El valor de x en el que se encuentra el mnimo es 0.02 que se corrsponde con y = 0.00

4.2. Scipy 45
PIMCD2013-python, Publicacin 1.0

La funcin sinc(x) tiene bastantes mnimos absolutos. En la imagen podemos ver sealados el encontrado y el
simtrico en rojo y la semilla en verde,

1.0 Difraccin por una rendija

0.8

0.6
Intensidad

0.4

0.2

0.00.10 0.05 0.00 0.05 0.10


ngulo ()
Nota: En el archivo se aade tambin el cdigo para la representacin sin embargo se explicar cuando hablemos
del mdulo Matplotlib.

4.2.2 Ejemplo: Encontrar mnimos en un intervalo definido.

Otro camino para encontrar mnimos es mediante el uso de fminbound como vemos en este ejemplo. Sea la funcin

( )
= + (4.2)

donde a, b, c, d son coeficientes y x es la variable. Para definirla en python vamos a crear una funcin cuyos
argumentos sean estos parmetros.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_minimizacion.py
# Proposito: Aprender como encontrar minimos locales con python.
#
# Origen: Propio a partir de la documentacion oficial.
# Autor: Jose Maria Herrera-Fernandez, Luis Miguel Sanchez-Brea
#
# Creacion: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy

46 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcion: Encuentra minimos locales de una funcion escalar en el intervalo (x1,x2 usando el met
"""

import scipy as sp # Importamos scipy como el alias sp


from scipy.optimize import fminbound # Importamos fmindbound desde scipy.optimize
import matplotlib.pyplot as plt # Importamos matplotlib.pyplot como el alias plt

def mi_funcion(x, a, b, c, d):


"""
(no definido, float, float,float,float,) -->(funcion simbolica)
* Descripcion: Funcion y = -cos(a*pi*x/b) + c*x*d
* Entradas:
- x = variable simbolica.
- a, b, c, d = Coeficientes de la funcion.
* Salidas:
- funcion simbolica y = -sp.cos(a*sp.pi*x/b) + c*x**d
* Test:
>>> import scipy as sp
>>> x = sp.arange(0,1,.01)
>>> print(mi_funcion(x, a = 1, b = 0.5, c = 0.2, d = 2))
[-1. -0.99800673 -0.9920347 -0.98210725 -0.96826316 -0.95055652
-0.92905649 -0.90384705 -0.87502668 -0.84270793 -0.80701699 -0.76809324
-0.72608863 -0.68116711 -0.63350399 -0.58328525 -0.53070679 -0.47597367
-0.41929929 -0.36090455 -0.30101699 -0.23986989 -0.17770131 -0.11475323
-0.05127052 0.0125 0.07631052 0.13991323 0.20306131 0.26550989
0.32701699 0.38734455 0.44625929 0.50353367 0.55894679 0.61228525
0.66334399 0.71192711 0.75784863 0.80093324 0.84101699 0.87794793
0.91158668 0.94180705 0.96849649 0.99155652 1.01090316 1.02646725
1.0381947 1.04604673 1.05 1.05004673 1.0461947 1.03846725
1.02690316 1.01155652 0.99249649 0.96980705 0.94358668 0.91394793
0.88101699 0.84493324 0.80584863 0.76392711 0.71934399 0.67228525
0.62294679 0.57153367 0.51825929 0.46334455 0.40701699 0.34950989
0.29106131 0.23191323 0.17231052 0.1125 0.05272948 -0.00675323
-0.06570131 -0.12386989 -0.18101699 -0.23690455 -0.29129929 -0.34397367
-0.39470679 -0.44328525 -0.48950399 -0.53316711 -0.57408863 -0.61209324
-0.64701699 -0.67870793 -0.70702668 -0.73184705 -0.75305649 -0.77055652
-0.78426316 -0.79410725 -0.8000347 -0.80200673]

"""
y = -sp.cos(a*sp.pi*x/b) + c*x**d
return y

Aleatoriamente escogemos a = 2, b = 0.5, c = 0.05 y d = 2


# Definimos los coeficientes a, b, c, d
a = 2
b = 0.5
c = 0.05
d = 2

y como intervalo (0.2,0.6),


# Definimos el intervalo de busqueda
x1 = 0.2
x2 = 0.6

Con estos datos ya podemos calcular el mnimo mediante fminbound

4.2. Scipy 47
PIMCD2013-python, Publicacin 1.0

# Calculamos del minimo local de la funcion entre x1 y x2


x_minimo = fminbound(mi_funcion,x1,x2, args = (a,b,c,d))

y por ltimo presentamos en pantalla


# Presentamos en pantalla el resultado
print (uEl minimo esta en x = %2.3f, y = %2.3f %(x_minimo, mi_funcion(x_minimo, a, b, c, d)))

El mnimo est en x = 0.500, y = -0.988

1.5 Busqueda de minimos en un intervalo dado

1.0

0.5
y

0.0

0.5

1.01.0 0.5 0.0 0.5 1.0 1.5 2.0


x

4.2.3 Ejemplo: Ajuste de una funcin.

Para este ejemplo imaginaremos que una heladera cuyas previsiones de venta en las cinco primeras horas viene
dada por la funcin,
2
( )
= 22 + (4.3)

siendo a, b, c y d coeficientes desconocidos que el propietario quiere saber para mejorar las ventas. Lo primero
que vamos a hacer es crear nuestro archivo .py segn la plantilla junto con la importacin de los mdulos que
vamos a utilizar.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_ajusteFunciones.py
# Propsito: Aprender el uso de curve_fit para ajustar funciones.
#
# Origen: Propio a partir del ejemplo de la documentacin oficial.

48 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

# Autor: Jos Mara Herrera-Fernandez, Luis Miguel Snchez-Brea


#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Ejemplo de cmo usar la funcin curve_fit perteneciente a scipy.optimize para
ajustar una funcin a una curva.
"""

from scipy.optimize import curve_fit # Importamos curve_fit de scipy.optimize


import scipy as sp # Importamos scipy como el alias sp
import matplotlib.pyplot as plt # Importamos matplotlib.pyplot como el alias plt.

Posteriormente definimos nuestra funcin de ventas,


def mi_funcion(x, a, b, c, d):
"""
* (x, float, float, float, float ) --> (mismo_tipo_x)
* Descripcin: definicin de una funcin general.
* Entradas:
- x = variable.
- a, b, c, d = Coeficientes de la funcin.
* Salidas:
- a*sp.exp(-b*x**2/(2*d**2)) + c * x
* Test:
>>> y = mi_funcion(5, 2.5, 1.3, 0.5,1)
2.50000021911
"""

return a*sp.exp(-b*x**2/(2*d**2)) + c * x

Al no tener datos experimentales reales, vamos a crearnos unos a partir de nuestra funcin. Es lo que en clculo
cientfico se denomina aadir ruido. Para ell nos definimos una nueva funcin que a partir de unos coeficientes
inventados crea un array y al que aadimos un array de numeros aleatorios de la misma dimension que x mediante
sp.random.normal que ponderamos con el factor k.
# Aadimos ruido a la funcin

x = sp.linspace(0, 5,30)
y = mi_funcion(x, 2.5, 1.3, 0.5,1)

def ruido(x,y,k):
"""
* (array, array, float) --> (array)
* Descripcin: definicin de una funcin general que mete ruido a la funcin creada.
De esta forma simulamos puntos experimentales.
* Entradas:
- x, y = arrays dimensionales.
* Salidas:
- yn = array dimensional con los datos experimentales simulados
* Test:
>>> x = sp.linspace(-5, 5,30)
>>> y = mi_funcion(x, 2.5, 1.3, 0.5,1)
>>> yn = ruido(x,y,k)
[ -1.6507892 -4.94424381 5.15178988 2.2186972 -5.84069527
4.33003238 -1.7888872 -0.30041015 -7.1204506 -2.283254
6.81036412 5.39317282 -8.57465789 -1.53478417 10.00896415

4.2. Scipy 49
PIMCD2013-python, Publicacin 1.0

4.6851419 4.97676784 8.65790741 1.10433784 6.66219667


-3.24728962 -2.48561578 6.97308239 1.3574805 14.38335617
7.68693699 7.89128524 -0.48446526 -6.50191937 10.92685615]
"""

yn = y + k * sp.random.normal(size = len(x))
return yn

Ajustamos nuestros datos experimentales recien creados a la funcin inicial mediante curve_fit. Los resultados los
vamos a almacener en coeficientes_optimizados y covarianza_estimada que es la covarianza de los coeficientes
optimizados,
# Ajustamos los datos experimentales a nuestra funcin y los almacenamos
coeficientes_optimizados, covarianza_estimada = curve_fit(mi_funcion, x, yn)

por ltimo presentamos en pantalla,


# Mostramos los coeficientes calculados
print "Coeficientes optimizados:", coeficientes_optimizados
print "Covarianza estimada:", covarianza_estimada

obteniendo,
Coeficientes optimizados: [ 2.57706857 64.3221008 0.50208527 6.86175853]
Covarianza estimada: [[ 4.92845597e-03 5.04794116e+06 -6.29090049e-05 2.69252336e+05]
[ 5.04794117e+06 2.20479587e+16 -3.76113582e+05 1.17601699e+15]
[ -6.29090094e-05 -3.76113634e+05 6.21152142e-05 -2.00615411e+04]
[ 2.69252337e+05 1.17601699e+15 -2.00615406e+04 6.27276188e+13]]

Nota: En el archivo se aade tambin el cdigo para la representacin sin embargo se explicar cuando hablemos
del mdulo Matplotlib.

4.2.4 Ejemplo: Funcin de Bessel de orden cero y uno.

Scipy dispone de un paquete muy interesante llamando special donde se encuentran funciones como airy o bessel,
http://docs.scipy.org/doc/scipy/reference/tutorial/special.html. Como ejemplo de este paquete nosotros vamos a
calcular la funcin de Bessel de orden cero. La ecuacin diferencial de Bessel viene definida por,
2 ( 2
2 + + 2 = 0
)
+ (4.4)
2
si ,
2 ( 2
2 + + 2 = 0
)
+ (4.5)
2
cuya solucin es,
( )+2
(1) 2
() = (4.6)
! ( + )!
=0

para n = 0 y n = 1 obtenemos las funciones de Bessel de orden 0 y 1. Estas funciones son de gran inportancia ya
que las funciones del resto de ordenes se pueden escribir en funcin de estas dos.
( )2 ( )4 ( )6
2 2 2 (4.7)
0 () = 1 2 + 2 2 +
(1!) (2!) (3!)

[ ( )2 ( )4 ( )6 ]

1 () = 1 2 2 + 2 2 2 2 + (4.8)
2 (1!2!) (2!3!) (3!4!)

en python,

50 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_bessel.py
# Propsito: Aprender el uso el paquete special de scipy.
#
# Origen: Propio.
# Autor: Jos Mara Herrera-Fernandez, Luis Miguel Snchez-Brea
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Clculo de los coeficientes de orden cero y uno de la funcin de Bessel
contenida en el paquete special.
"""
from scipy import special # Importamos scipy.special
import scipy as sp # Importamos scipy como el alias sp
import matplotlib.pyplot as plt # Importamos matplotlib.pyplot como el alias plt.

# Creamos el array dimensional


x = sp.arange(0,50,.1)

# Calculamos los coeficientes de orden cero.


j0 = special.j0(x)

# Calculamos los coeficientes de orden uno.


j1 = special.j1(x)

4.2. Scipy 51
PIMCD2013-python, Publicacin 1.0

Orden cero
1.0 Orden uno

0.5
J(x)

0.0

0.5
0 10 20 30 40 50
x

Nota: En el archivo se aade tambin el cdigo para la representacin sin embargo se explicar cuando hablemos
del mdulo Matplotlib.

4.2.5 Ejemplo: Clculo de integrales

Gracias a integrate de Scipy tambin podemos realizar integrales en Python. La primera integral que vamos a
realizar es

= () (4.9)

en el intervalo de 0 a
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_integrales.py
# Propsito: Aprender como integrar con python.
#
# Origen: Propio .
# Autor: Jos Mara Herrera-Fernandez, Luis Miguel Snchez-Brea
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy
# Licencia: GPL
#----------------------------------------------------------------------

52 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

"""
Descripcin: Ejemplo de cmo usar la funcin integrate para realizar integrales
numricas en python.
"""

import scipy as sp # Importamos scipy como el alias sp


from scipy import integrate # Importamos integrate de scipy

# Ejemplo 1: Definicin de la integral para la funcin y = e^(-x).

def integral_1(limite_inferior, limite_superior, mostrar_resultados):


"""
(float,float, bool) -->(float, float)
* Descripcin: Calculo de la integral de limite_inferior a limite_superior de
la funcin y = e^(-x)
* Entradas:
- limite_inferior = inicio del intervalo de integracin.
- limite_superior = fin del intervalo de integracin.
* Salidas:
- tupla con las soluciones de la integral
* Test:
>>> integral_1(limite_inferior = 0, limite_superior = 5)
La integral entre 0.00 y 5.00 es
(0.9932620530009145, 1.102742400728068e-14)
"""
# Defino la funcin e^(-x)
exponencial_decreciente = lambda x: sp.exp(-x)

# Presento en pantalla los resultados si quiero


if mostrar_resultados == True:
print (La integral entre %2.2f y %2.2f es % (limite_inferior, limite_superior))
print(integrate.quad(exponencial_decreciente,limite_inferior,limite_superior))

# Los devuelvo
return integrate.quad(exponencial_decreciente ,limite_inferior,limite_superior)

donde podemos ver que hemos creado un if para mostrar o no los resultados en pantalla. Ejecutando,
>>> integral_1(limite_inferior = 0, limite_superior = sp.inf, mostrar_resultados = True)
La integral entre 0.00 y inf es
(1.0000000000000002, 5.842606742906004e-11)

De la misma forma podemos adems tener en cuenta coeficientes de la funcin que pueden variar,
def integral_2(limite_inferior, limite_superior,a,b, mostrar_resultados):
"""
(float,float,float, float, bool) -->(float, float)
* Descripcin: Calculo de la integral de limite_inferior a limite_superior de
la funcin y = ax^(b)
* Entradas:
- limite_inferior = inicio del intervalo de integracin.
- limite_superior = fin del intervalo de integracin.
- a,b = coeficientes de la funcin
* Salidas:
- y = integral
- err = error cometido.
* Test:
>>> y = integral_2(limite_inferior = 0, limite_superior = 1,a = 4, b = 5, mostrar_resultados =
La integral vale 0.67, y el error cometido 0.00
"""

# Defino la funcin y = a*x^(b)


funcion = lambda x,a,b : a*x**b

4.2. Scipy 53
PIMCD2013-python, Publicacin 1.0

# Calculo la integral
y, err = integrate.quad(funcion, limite_inferior, limite_superior, args=(a,b,))

# Presento en pantalla los resultados si quiero


if mostrar_resultados:
print (La integral vale %2.2f, y el error cometido %2.2f % (y, err))

# Los devuelvo
return y, err

donde tambin hemos aadido el if con una pequea modificacin. Python nos permite ahorrarnos == True.
Ejecutando,
>>> y = integral_2(limite_inferior = 0, limite_superior = 1,a = 2, b = 3, mostrar_resultados = Tru
La integral vale 0.50, y el error cometido 0.00

4.2.6 Ejemplo: Interpolacin

Otra opcin interesante de python es poder interpolar a partir de nuestros datos experimentales. Como ejemplo
interpolaremos en una dimensin mediante interpolate.interp1d,
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_interpolar.py
# Propsito: Aprender como interpolar con python.
#
# Origen: Propio a partir de la documentacin oficial.
# Autor: Jos Mara Herrera-Fernandez, Luis Miguel Snchez-Brea
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Ejemplo de cmo hacer una interpolacin en python.
"""
import scipy as sp # Importamos scipy como el alias sp
from scipy import interpolate # Importamos interpolate de scipy
import matplotlib.pyplot as plt # Importamos matplotlib.pyplot como el alias plt

# Creamos el array dimensional


x = sp.linspace(0,3,10)

# Evaluamos x en la funcin y = e^(-x/3) (generando nuestros "datos experimentales")


y = sp.exp(-x/3.0)

# Interpolamos
interpolacion = interpolate.interp1d(x, y)

# Creamos un nuevo array dimensional con ms puntos en el mismo intervalo


x2 = sp.linspace(0,3,100)

# Evaluamos x2 en la interpolacin
y2 = interpolacion(x2)

54 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

# Creamos la figura
plt.figure

# Dibujamos las dos grficas juntas


plt.plot(x, y, o, x2, y2, -)

# Aadimos la leyenda
plt.legend((Datos conocidos, Datos experimentales))

# aadimos las etiquetas


plt.xlabel(Eje x)
plt.ylabel(Eje y)

# Mostramos en pantalla
plt.show()

1.0
Datos conocidos
0.9 Datos experimentales

0.8

0.7
Eje y

0.6

0.5

0.4

0.30.0 0.5 1.0 1.5 2.0 2.5 3.0


Eje x

4.2.7 Ejemplo: Clculo de las raices de un polinomio

Scipy posibilita la opcin de clacular las raices de un polinomio de una forma rpida y sencilla,
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_scipy_raicesPolinomio.py
# Propsito: Aprender como calcular las raices de un polinomio con python.
#
# Origen: Propio a partir de la documentacin oficial.
# Autor: Jos Mara Herrera-Fernandez, Luis Miguel Snchez-Brea

4.2. Scipy 55
PIMCD2013-python, Publicacin 1.0

#
# Creacin: 20 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Ejemplo de cmo calcular las raices de un polinomio mediante scipy.
"""

import scipy as sp # Importamos scipy como el alias sp


import matplotlib.pyplot as plt # Importamos matplotlib.pyplot como el alias plt

# Creamos un polinomio
polinomio = [1.3,4,.6,-1] # polinomio = 1.3 x^3 + 4 x^2 + 0.6 x - 1

# Creamos un array dimensional


x = sp.arange(-4,1,.05)

# Evaluamos el polinomio en x mediante polyval.


y = sp.polyval(polinomio,x)

# Calculamos las raices del polinomio


raices = sp.roots(polinomio)

# Evaluamos el polinomio en las raices


s = sp.polyval(polinomio,raices)

# Las presentamos en pantalla


print ("Las raices son %2.2f, %2.2f, %2.2f. " % (raices[0], raices[1], raices[2]))

obteniendo,
Las raices son -2.82, -0.67, 0.41.

56 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

5 Clculo de las raices de un polinomio


y(x)
Raices del polinomio
0

10
y

15

20

25 4 3 2 1 0 1
x

4.3 Matplotlib

Autores Jos Mara Herrera Fernndez, Luis Miguel Snchez Brea

Contenidos de este captulo:


Funciones principales
Ejemplo: grfica simple en una dimensin
Ejemplo: grfica completa en una dimensin
Ejemplo: Varas grficas individuales en una figura
Ejemplo: Grfica en dos dimensiones
Ejemplo: Grfica en tres dimensiones

Matplotlib es el mdulo de dibujo de grficas 2D y 3D que vamos a utilizar aunque no es el nico exis-
tente. Matplotlib tiene multitud de libreras de las cuales nosotros, por semejanza a Matlab, utilizaremos
pyplot. Recomendamos al lector visitar http://matplotlib.sourceforge.net/, donde puede encontrar multitud de
programas y ejemplos de como hacer dibujos con Matplotlib. La documentacin oficial se encuentra en
http://matplotlib.sourceforge.net/contents.html no obstante, a lo largo de esta seccin veremos algunas de las fun-
ciones ms interesantes.
Para poder utilizar el mdulo Matplotlib en nuestros programas primero debemos importarlo. Por comodidad los
mdulos de nombre ms extenso suelen renombrarse para optimizar su importacin. En nuestro caso vamos a
importarlo como plt incluyendo en el inicio de nuestro programa la siguiente lnea de cdigo:
import matplotlib.pyplot as plt

En la Figura 3 podemos ver que si escribimos esta lnea de comando en una consola, con solo poner plt se
nos muestra en pantalla la ayuda para este mdulo. Si adems tras plt aadimos un punto, se nos muestra un

4.3. Matplotlib 57
PIMCD2013-python, Publicacin 1.0

Figura 4.2: Figura 2. Ejemplo de grfica realizada con la librera pyplot de Matplotlib (DOE de fase).

desplegable con todas las funciones en este mdulo. Si pinchamos en una de ellas, al igual que antes, se nos abre
una ventana de ayuda que nos indica el uso del comando.
como ya explicamos en temas anteriores tambin podemos importar matplotlib mediante la sentencia
from matplotlib import pyplot

donde para ejecutar la funcin debemos usar


pyplot.funcion()

o cargar todas las funciones,


from matplotlib import *

4.3.1 Funciones principales

El mdulo Matplotlib (al igual que la mayora de los mdulos) es enorme y explicar todas y cada una de las
funciones nos llevara demasiado tiempo as que analizaremos las ms interesnates para un usuario principiante.
figure(num, figsize, dpi, facecolor, edgecolor, frameon) > Crea una nueva figura. Se puede utilizar sin argu-
mentos. Devuelve un identificador a la figura.
num = numeracin de la figura, si num = None, las figuras se numeran automticamente.
figsize = w, h tuplas en pulgadas. Tamao de la figura
dpi = Resolucin de la imagen en puntos por pulgada.
facecolor = Color del rectngulo de la figura.
edgecolor = Color del permetro de la figura.
frameon = Si es falso, elimina el marco de la figura.
>>> figure(num = None, figsize = (8, 6), dpi = 80, facecolor = w, edgecolor = k)

que nos crea el objeto


<matplotlib.figure.Figure object at 0x3938e50>

subplot(numRows, numCols, plotNum) > Permite incluir varias grficas en una nica figura.
numRows = Nmero de filas

58 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

Figura 4.3: Figura 3. Importacin del mdulo matplotlib como plt en una consola interactiva de Eclipse.

4.3. Matplotlib 59
PIMCD2013-python, Publicacin 1.0

numCols = Nmero de columnas


plotNum = Nmero de grfica
>>> subplot(211)

es la primera grfica de la primera lnea. Ejecutando,


<matplotlib.axes.AxesSubplot object at 0x393de90>

plot(x, y, linestyle, linewidth, marker) > Permite incluir varias grficas en una nica figura.
x = Abcisas.
y = Ordenadas. Tanto x como y pueden ser abcisas tuplas, listas o arrays. La nica condicin es que el
tamao de ambas debe ser el mismo ya que en caso contrario python nos devolver un fallo de tipo dimesin.
Tambin se puede hacer una grfica sin especificar la coordenada x.
linestyle = color y tipo de dibujar la grfica. Por ejemplo k- -
linewidth = ancho de lnea.
marker = Marcador.
por ejemplo,
>>> plt.plot(x, y, k--, linewidth = 2)

Dibuja la curva y(x) en trazo discontinuo de color negro con ancho de lnea de tamao 2. La funcin plot devuelve
una lista. El nmero de elementos depende del nmero de plots realizados. El tipo retornado para cada elemento
de la lista es matplotlib.lines.Lines2D. Analizando cada elemento se puede extraer informacin que caracteriza al
grfico (formato de marcador, colores usados,...).
>>> from matplotlib import pyplot
>>> x = range(10)
>>> y = x
>>> a = pyplot.plot(x,y)
>>> len(a)
1
>>> a[0].get_color()
b
>>> a[0].get_ls()
-
>>> a[0].get_marker()
None

Tipos Los tipos ms comunes son:


- lnea slida
- - lnea a rayas
-. lnea con puntos y rayas
: lnea punteada
Colores
b Azul
g Verde
r Rojo
c Cin
m Magenta
y Amarillo
k Negro

60 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

w Blanco
Tambin se puede escribir el color de las siguientes formas: nombres (green); cadenas hexadecimales
(#008000); tuplas con convencin RGB (0,1,0); intensidades de escala de grises (0.8).
Marcadores
Los tipos principales son:
[ + | * | , | . | 1 | 2 | 3 | 4 | < | > | D | H | ^ | _ | d | h | o | p | s | v | x ].
Fillstyle Relleno de smbolo elegido para representar cada dato.
[full | left | right | bottom | top]
show() Presenta las figuras en pantalla mediante una ventana en la que podemos interactuar. Este comando se
debe aadir siempre que necesitemos obervar nuestra grfica ya que sino python realizar el clculo pero no
presentar la imagen. Lo usual es ponerlo al final del programa posibilitando aas la llamada a todas las figuras
que se encuentren en el mismo.
>>> plt.show()

legend(labels, loc) Coloca una leyenda. Cuando se presentan varas curvas simultneamente este comando identi-
fica cada una. Puede utilizarse sin argumentos si en cada funcin plot (o equivalente) se ha incluido el argumento
label, que es un texto para identificar la curva.
>>> plt.legend( (Etiqueta1, Etiqueta2, Etiqueta3), loc = upper left)

plt.xlabel(s, comandos_optativos) Etiqueta el eje de abcisas de la grfica actual. plt.ylabel(s, coman-


dos_optativos) Etiqueta el eje de abcisas de la grfica actual. plt.title(s, comandos_optativos) Etiqueta el eje
de abcisas de la grfica actual.
s = Texto que aparecer en el ttulo
comandos_optativos = En esta etiqueta englobamos todos los modificadores de la fuente etc.
>>> plt.xlabel("Tiempo (s)", fontsize = 20)
>>> plt.ylabel("Distancia (m)", fontsize = 20)
>>> plt.title("velocidad (m/s)", fontsize = 20)

plt.text(x, y, s, comandos_optativos) Aade el texto s en las coordenadas espaciales x, y. El texto se puede


modificar como otro texto (tamao, color, etc.).
x, y = Coordenadas espaciales horizontal y vertical.
s = Texto que queremos aadir
>>> plt.text(5, 7, "Ms texto", fontsize = 12)

axis() Establece u obtiene las propiedades de los ejes. Podemos establecer el rango de coordenadas en x e y que
queremos mostrar en el grfico. Del mismo modo, podemos seleccionar la relacin de aspecto entre las coordena-
das x e y.
axis(), devuelve los lmites de los ejes ([xmin, xmax, ymin, ymax])
axis(v), establece los valores lmites de los ejes a v = [xmin, xmax, ymin, ymax]
axis(off), elimina lneas de ejes y etiquetas
axis(equal), cambia los lmites de x e y para que los incrementos de x e y tengan la misma longitud (un
crculo parece un crculo)
axis(scaled), cambia las dimensiones del plot para conseguir la misma longitud de intervalo en x e y.
axis(tight), cambia los ejes para que se muestren todos los datos.
axhline(y, xmin, xmax) Con esos valores de los parmetros predeterminados establecidos, la lnea se ajusta al
rango representado por los correspondientes ejes.
y, array con los datos

4.3. Matplotlib 61
PIMCD2013-python, Publicacin 1.0

xmin = 0, valor mnimo


xmax = 1, valor mximo
>>> plt.axhline(y = .5, xmin = 0.25, xmax = 0.75

hold() Si el parmetro es True, podemos poner ms curvas en la misma grfica. Si el parmetro es False, entonces
al escribir una nueva curva, las anteriores se borran.
grid() Establece la malla a True (visible) o False (oculta).
>>> plt.grid(True)
>>> plt,grid(color = r, linestyle = , linewidth = 2)

savefig(ruta) Guarda la grfica en un archivo.


ruta: ruta y nombre de archivo. Los tipos de datos pueden ser .png, .eps, .pdf, .ps, .svg.
dpi = None: resolucin de la imagen en puntos por pulgada
facecolor = w: color del rectngulo de la figura
edgecolor = w: color del permetro de la figura
orientation = portrait: orientacin del papel (landscape)
format = None : (png, pdf, ps, eps y svg).
transparent = False, si es True, crear una grfica de fondo transparente.
>>> plt.savefig(figura3.eps, dpi = 300) #guarda la grfica con 300dpi (puntos por pulgada)

close() Cierra la grfica


Asimismo, podemos usar la sintaxis de Latex para hacer ms precisas y elegantes nuestras etiquetas. Lo nico que
debemos hacer es poner nuestra cadena de texto de la siguiente forma: rcadena latex. Por ejemplo:
xlabel(r$\lambda (\AA)$)

se muestra como ()

4.3.2 Ejemplo: grfica simple en una dimensin

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Carga de los mdulos necesarios


import scipy as sp
import matplotlib.pyplot as plt

# Creamos el array x de cero a cien con cien puntos


x = sp.linspace(0, 10, 100)

# Creamos el array y conde cada punto es el seno de cada elemento de x


y = sp.sin(x)

# Creamos una figura


plt.figure()

# Representamos
plt.plot(x,y)

# Mostramos en pantalla
plt.show()

62 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

1.0

0.5

0.0

0.5

1.00 2 4 6 8 10

4.3.3 Ejemplo: grfica completa en una dimensin

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_matplotlib_grafica_completa.py
# Propsito: Aprender a realizar una grfica lo ms completa posible
#
# Origen: Propio.
# Autor: Luis Miguel Snchez-Brea,Jos Mara Herrera-Fernandez
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: numpy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Doble grfica senoidal donde se muestran la mayora de los complementos
que se pueden aadir a una grfica
"""

import numpy as np # Cargamos numpy como el alias np


import matplotlib.pyplot as plt # Crgagamos matplotlib.pyplot como el alias plt

# Definimos el periodo de la funcin

4.3. Matplotlib 63
PIMCD2013-python, Publicacin 1.0

periodo = 0.5

# Definimos el array dimensional


x = np.linspace(0, 2, 1000)

# Definimos la funcin senoidal


y = np.sin(2*np.pi*x/periodo)

# Creamos la figura
plt.figure()

# Dibujamos en negro discontinuo con etiqueta y1


plt.plot(x, y, k--, linewidth = 2, label = y1)

# Mantenemos la misma figura parta la siguiente grfica


plt.hold(True)

# Esta vez dibujamos - y en rojo co etiqueta y2


plt.plot(x,-y,r, linewidth = 2, label = y2)

# Aadimos la leyenda
plt.legend(loc = 2)

# Aadimos las etiquetas poniermo en Latex "mu" smbolo de micras


plt.xlabel(r"$x (\mu m)$", fontsize = 24, color = (1,0,0))
plt.ylabel(r"$y (\mu m)$", fontsize = 24, color = blue)

# Aadimos texto
plt.text(x = 1, y = 0.0, s = uT = 0.05, fontsize = 24)

# Aadimos la rejilla
plt.grid(True)
plt.grid(color = 0.5, linestyle = --, linewidth = 1)

# Aadimos los ejes


plt.axis(tight)

# Aadimos el ttulo
plt.title((a),fontsize = 28, color = 0.75, verticalalignment = baseline, horizontalalignment

# Guardamos
plt.savefig(plotCompleta.png)

# Mostramos en pantalla
plt.show()

64 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

(a)
y1
y2
0.5

T = 0.05
y(m)

0.0

0.5

0.0 0.5 1.0 1.5 2.0


x(m)
4.3.4 Ejemplo: Varas grficas individuales en una figura

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_matplotlib_subplot.py
# Propsito: Aprender a mostrar varas grficas separadas en una figura
#
# Origen: Propio.
# Autor: Luis Miguel Snchez-Brea,Jos Mara Herrera-Fernandez
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: numpy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: En este ejemplo se muestra como realizar la presentancin de varas
grficas individuales en una misma figura mediante "subplot"
"""

import numpy as np # Cargamos numpy como el alias np


import matplotlib.pyplot as plt # Crgagamos matplotlib.pyplot como el alias plt

# Definimos el periodo de la grfica senoidal

4.3. Matplotlib 65
PIMCD2013-python, Publicacin 1.0

periodo = 2

# Definimos el array dimensional


x = np.linspace(0, 10, 1000)
# Definimos la funcin senoidal
y = np.sin(2*np.pi*x/periodo)

# Creamos la figura
plt.figure()

# Primera grfica
plt.subplot(2,2,1)
plt.plot(x, y,r)

# Segunda grfica
plt.subplot(2,2,2)
plt.plot(x, y,g)

# Tercera grfica
plt.subplot(2,2,3)
plt.plot(x, y,b)

# Cuarta grfica
plt.subplot(2,2,4)
plt.plot(x, y,k)

# Mostramos en pantalla
plt.show()

1.0 1.0

0.5 0.5

0.0 0.0

0.5 0.5

1.00 2 4 6 8 10 1.00 2 4 6 8 10
1.0 1.0

0.5 0.5

0.0 0.0

0.5 0.5

1.00 2 4 6 8 10 1.00 2 4 6 8 10

66 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

4.3.5 Ejemplo: Grfica en dos dimensiones

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_matplotlib_imshow.py
# Propsito: Aprender a realizar una grfica en 2D
#
# Origen: Propio.
# Autor: Luis Miguel Snchez-Brea,Jos Mara Herrera-Fernandez
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: numpy, matplotlib
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: En este ejemplo se muestra como realizar una grfica en dos dimensiones
mediante imshow
"""

import numpy as np # Cargamos numpy como el alias np


import matplotlib.pyplot as plt # Crgagamos matplotlib.pyplot como el alias plt

# Creamos una figura


plt.figure()

# Creamos los arrays dimensionales


x = np.arange(-5, 5, 0.01)
y = np.arange(-5, 5, 0.01)

# Obtenemos las corrdenadas resultantes de esos arrays


X, Y = np.meshgrid(x, y)

# Definimos la grfica sen (x^2 + y^2)


fxy = np.sin(X**2+Y**2)

# Representamos
plt.imshow(fxy);

# Aadimos una colorbar


plt.colorbar();

# Mostramos en pantalla
plt.show()

4.3. Matplotlib 67
PIMCD2013-python, Publicacin 1.0

0 1.0
0.8
200 0.6
0.4
400 0.2
0.0
600 0.2
0.4
800 0.6
0.8

0 200 400 600 800 1.0

4.3.6 Ejemplo: Grfica en tres dimensiones

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

#----------------------------------------------------------------------
# Nombre: ejemplo_matplotlib_grafica_superficie3d.py
# Propsito: Aprender como leer una image y representar una grafica en 3D.
#
# Origen: Propio .
# Autor: Jos Mara Herrera-Fernandez
#
# Creacin: 18 de Septiembre de 2013
# Historia:
#
# Dependencias: scipy, mpl_toolkits, matplotlib, numpy
# Licencia: GPL
#----------------------------------------------------------------------

"""
Descripcin: Ejemplo de cmo usar la funcin integrate para realizar integrales
numricas en python.
"""

from mpl_toolkits.mplot3d import Axes3D # Cargo Axes3D de mpl_toolkits.mplot3d


from scipy.misc import imread # Cargo imread de scipy.misc

68 Captulo 4. Mdulos Cientficos


PIMCD2013-python, Publicacin 1.0

import numpy as np # Cargo numpy como el aliaas np


import matplotlib.pyplot as plt # Cargo matplotlib.pyplot en el alias sp

# Leo una imagen y la almaceno en imagen_superficial


imagen_superficial = imread(fondo.jpg)

# Creo una figura


plt.figure()

# Muestro la imagen en pantalla


plt.imshow(imagen_superficial)

# Aado etiquetas
plt.title(Imagen que usaremos de superficie)
plt.xlabel(u# de pxeles)
plt.ylabel(u# de pxeles)

# Creo otra figura y la almaceno en figura_3d


figura_3d = plt.figure()

# Indicamos que vamos a representar en 3D


ax = figura_3d.gca(projection = 3d)

# Creamos los arrays dimensionales de la misma dimensin que imagen_superficial


X = np.linspace(-5, 5, imagen_superficial.shape[0])
Y = np.linspace(-5, 5, imagen_superficial.shape[1])

# Obtenemos las coordenadas a partir de los arrays creados


X, Y = np.meshgrid(X, Y)

# Defino la funcin que deseo representar


R = np.sqrt(X ** 2 + Y ** 2)
Z = np.sin(R)

# Reescalamos de RGB a [0-1]


imagen_superficial = imagen_superficial.swapaxes(0, 1) / 255.

# meshgrid orienta los ejes al revs luego hay que voltear


ax.plot_surface(X, Y, Z, facecolors = np.flipud(imagen_superficial))

# Fijamos la posicin inicial de la grafica


ax.view_init(45, -35)

# Aadimos etiquetas
plt.title(uImagen sobre una grafica 3D)
plt.xlabel(Eje x)
plt.ylabel(Eje y)
# Mostramos en pantalla
plt.show()

4.3. Matplotlib 69
PIMCD2013-python, Publicacin 1.0

0
Imagen que usaremos de superficie

20

40
# de pxeles

60

80

100

0 20 40 60 80 100 120 140


# de pxeles

Imagen sobre una grafica 3D

1.0
0.5
0.0
0.5
6
4 1.0
2 6
Eje 0 4
x 2
2 0 y
4 4
2 Eje
6 6

70 Captulo 4. Mdulos Cientficos


CAPTULO 5

Ecuaciones de Maxwell en el vaco

Autor Luis Miguel Snchez Brea

Contenidos de este captulo:


Introduccin
Programacin
Haces de Gauss

Herramientas utilizadas en este tutorial:


numpy: manipulacin de datos
scipy: Herramientas matemticas
Archivos necesarios para la clase interferencias:
camposXY.py. Archivo con las funciones principales de campos camposXY.py
fuentesXY.py. Archivo con las funciones principales de fuentes fuentesXY.py
Descarga de archivos:
Ejemplo de onda esfrica onda_esferica.py
Ejemplo animado de onda esfrica onda_esferica_animado.py
Ejemplo de ondas planas onda_plana.py
Ejemplo de haces de gauss haz_gauss.py

5.1 Introduccin

E = E1 + E2

tambin es una solucin. Sin embargo, el campo no es un parmetro observable, sino que lo es el promedio
temporal del vector de Poynting, que se define como
1
S E B,
0

con tiene unidades de [S] = /2 . Al particularizar al caso de ondas armnicas planas tenemos

1 0 2
S = |E| u ,
2 0
: : (, )

71
PIMCD2013-python, Publicacin 1.0

5.2 Programacin

Debido a la sencillez conceptual de las interferencias, las utilizaremos para analizar los distintos tipos de pro-
gramacin que se puede realizar con Python, como es la programacin con scripts (todo el cdigo en un mismo
archivo lineal), la programacin funcional (se escriben funciones que simplifican lo clculos) y la programacin
con clases (donde funciones y datos estn ntimamente relacionados). Finalmente veremos un procedimiento sen-
cillo para desarrollar vdeos, simulando un interfermetro de Michelson.
tamano=100*um
x=sp.linspace(-tamano,tamano, 256)
y=sp.linspace(-tamano,tamano, 256)
X,Y=sp.meshgrid(x,y)

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: onda plana
#-------------------------------------

from __future__ import division

import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)

from camposXY import campoXY, um, mm, grados


from fuentesXY import fuenteXY

def onda_plana(A=1, teta=0*grados, phi=0*grados):


"""
Generacion de una onda plana
"""

#definicion de parametros iniciales


tamano = 250 * um
npixels = 256
#Generacion de la clase
x = sp.linspace(-tamano / 2, tamano / 2, npixels)
y = sp.linspace(-tamano / 2, tamano / 2, npixels)
X, Y = sp.meshgrid(x, y)
wavelength = 0.6328 * um
k = 2 * sp.pi / wavelength

u = A * sp.exp(1.j * k * (X * sp.sin(teta) * sp.sin(phi) + Y * sp.cos(teta) * sp.sin(phi))


#carga de la onda plana
#dibujar y guardar

IDfig = plt.figure()
IDax = IDfig.add_subplot(111)
extension = [x.min(), x.max(), y.min(), y.max()]
angulo = sp.angle(u) #/ sp.pi
angulo[angulo == 1] = -1
IDimagen = plt.imshow(angulo, interpolation = bilinear, aspect = auto,origin = lower
plt.xlabel("$x (\mu m)$", fontsize = 20)
plt.ylabel("$y (\mu m)$", fontsize = 20)
titulo="$A =$ %4.2f $\phi =$ %4.2f $^{0}, \Theta =$ %4.2f $^0$" %(A, phi*180/sp.pi, teta
plt.suptitle(titulo, fontsize = 20)

72 Captulo 5. Ecuaciones de Maxwell en el vaco


PIMCD2013-python, Publicacin 1.0

plt.axis(scaled)
plt.axis(extension)
plt.colorbar()
IDimagen.set_cmap("RdBu")
plt.clim(vmin = -sp.pi, vmax = sp.pi)

onda_plana(A=1, teta=45*grados, phi=1*grados)


onda_plana(A=1, teta=0*grados, phi=0*grados)
plt.show()

A = 1.00 = 1.00 0 , = 45.00 0


100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)

5.2. Programacin 73
PIMCD2013-python, Publicacin 1.0

A = 1.00 = 0.00 0 , = 0.00 0


100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: onda esferica
#-------------------------------------

from __future__ import division

import scipy as sp
import matplotlib.pyplot as plt

um=1

def onda_esferica(A = 1, z0 = -1000 * um):


"""
Generacion de una onda plana
"""

#definicion de parametros iniciales


tamano = 250 * um
npixels = 256
#Generacion de la clase
x = sp.linspace(-tamano / 2, tamano / 2, npixels)
y = sp.linspace(-tamano / 2, tamano / 2, npixels)
X, Y = sp.meshgrid(x, y)
wavelength = 0.6328 * um
k = 2 * sp.pi / wavelength

74 Captulo 5. Ecuaciones de Maxwell en el vaco


PIMCD2013-python, Publicacin 1.0

#Centrado radio de la mascara y distancia al origen emisor


R2 = X ** 2 + Y** 2
Rz = sp.sqrt(X ** 2 + Y ** 2 + z0 ** 2)

#Onda esferica
u = A * sp.exp(-1.j * sp.sign(z0) * k * Rz) / Rz

IDfig = plt.figure()
IDax = IDfig.add_subplot(111)
extension = [x.min(), x.max(), y.min(), y.max()]
angulo = sp.angle(u)
angulo[angulo == 1] = -1
IDimagen = plt.imshow(angulo, interpolation = bilinear, aspect = auto,origin = lower
plt.xlabel("$x (\mu m)$", fontsize = 20)
plt.ylabel("$y (\mu m)$", fontsize = 20)
titulo="fase A = %4.2f z0 = %4.2f mm" %(A, z0/1000*um)
plt.suptitle(titulo, fontsize = 20)
plt.axis(scaled)
plt.axis(extension)
plt.colorbar()
IDimagen.set_cmap("RdBu")
plt.clim(vmin = -sp.pi, vmax = sp.pi)

onda_esferica(A=1, z0 = -1000 * um)


onda_esferica(A=1, z0 = -5000 * um)
onda_esferica(A=1, z0 = 5000 * um)

plt.show()

fase A = 1.00 z0 = -1.00 mm


100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)

5.2. Programacin 75
PIMCD2013-python, Publicacin 1.0

fase A = 1.00 z0 = -5.00 mm


100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)
fase A = 1.00 z0 = 5.00 mm
100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)

76 Captulo 5. Ecuaciones de Maxwell en el vaco


PIMCD2013-python, Publicacin 1.0

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Emision de una onda esferica
#-------------------------------------

import time, gobject, gtk #@UnusedImport


import scipy as sp
import matplotlib
matplotlib.use(GTKAgg)
import matplotlib.pyplot as plt
import matplotlib.cm as cm

um=1; mm=1000*um; m=1000*mm; s=1; fs=1e-15*s

wavelength=0.6328*um
k = 2 * sp.pi / wavelength
c= 299792.458 *m/s

w=c*k

#area de visualizacion
tamano=1.25*um
x=sp.linspace(-tamano, tamano, 250)
z=sp.linspace(-tamano, tamano, 250)
X,Z=sp.meshgrid(x, z)

#calculo de la intensidad
R = sp.sqrt(X** 2 + Z ** 2)
E_theta=sp.cos(k*R)/R
intensidad = abs(E_theta) ** 2
intensidad=sp.log(intensidad+1)
#fase=sp.angle(E_theta)

#Se dibuja por primera vez


fig = plt.figure(1)
a = plt.subplot(111)
im = a.imshow(intensidad, cmap=cm.jet)
manager = plt.get_current_fig_manager()

#tiempo
t=sp.linspace(0,50000*fs,1001)

#bucle
i=0
def updatefig(*args):
global t, i
E_theta=sp.cos((k*R-w*t[i]))/R
intensidad = abs(E_theta) ** 2
intensidad=sp.log(intensidad+1)
#fase=sp.angle(E_theta)

im.set_array(intensidad)
titulo="t = %4.0f fs" %(t[i]/fs)
plt.title(titulo)
manager.canvas.draw()
i += 1
if i==len(t):
return False
return True

5.2. Programacin 77
PIMCD2013-python, Publicacin 1.0

gobject.idle_add(updatefig)
plt.show()

50

100

150

200

0 50 100 150 200

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: haz gaussiano
#-------------------------------------

from __future__ import division

import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)

from camposXY import campoXY, um, mm, grados


from fuentesXY import fuenteXY

def haz_gauss(A = 1, w = (250 * um, 250 * um)):


#definicion de parametros iniciales
tamano = 1000 * um
x = sp.linspace(-tamano / 2, tamano / 2, 256)
y = sp.linspace(-tamano / 2, tamano / 2, 256)
X,Y=sp.meshgrid(x,y)
wavelength = 0.6238 * um
k = 2 * sp.pi / wavelength
wx, wy = w

78 Captulo 5. Ecuaciones de Maxwell en el vaco


PIMCD2013-python, Publicacin 1.0

#Definicion de la amplitud
u = A * sp.exp(-X ** 2 / (2 * wx ** 2) - Y** 2 / (2 * wy ** 2))
intensidad=abs(u)**2

IDfig = plt.figure()
IDax = IDfig.add_subplot(111)
extension = [x.min(), x.max(), y.min(), y.max()]
IDimagen = plt.imshow(intensidad ,origin = lower, extent = extension)
plt.xlabel("$x (\mu m)$", fontsize = 20)
plt.ylabel("$y (\mu m)$", fontsize = 20)
plt.axis(scaled)
plt.axis(extension)
plt.colorbar()
IDimagen.set_cmap("gist_heat")

haz_gauss( w = (250 * um, 250 * um))


haz_gauss( w = (250 * um, 125 * um))
plt.show()

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)

5.2. Programacin 79
PIMCD2013-python, Publicacin 1.0

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)

5.3 Haces de Gauss

Veamos ahora el proceso de interferencia de 2 haces de Gauss. Estos hace se pueden definir como

2 2
( ) ( )
0
(, , ) = 0 exp 2 exp + ()
() () 2()

donde
0
02 =

( )2

() = 0 1+
0

[ ]

() = 1 + ( )2
0

Este tipo de haces se puede programar fcilmente. Asumamos que estamos en el foco del haz z=0 y los haces estn
rotados. Entonces tambin se van a producir interferencias entre los haces.

80 Captulo 5. Ecuaciones de Maxwell en el vaco


CAPTULO 6

Polarizacin

Autores Luis Miguel Snchez Brea y Jos Luis Vilas Prieto

Contenidos de este captulo:


Introduccin
Programa interactivo para el anlisis de la polarizacin
Definiciones de polarizadores
Definiciones de estados de luz polarizada
Clculo de la intensidad de un vector de polarizacin
Polarizacin bsica
Ley de Malus
Efecto Zenon

Herramientas utilizadas en este tutorial:


Mdulo con las funciones principales polarizacion.py
Contenidos de los archivos:
polarizacion.py:
rotacion(). Matriz de un rotador.
polarizadorLineal(). Matriz de un polarizador lineal.
polarizadorRetardador(). Matriz de un retardador lineal.
laminaLambdaCuartos(). Matriz de un retardador de cuarto de onda.
laminaLambdaMedios(). Matriz de un retardador de media onda.
luzLineal(). Vector de Jones de luz linealmente polarizada.
luzCircular(). Vector de Jones de luz polarizada circular.
luzEliptica(). Vector de Jones de luz elpticamente polarizada.
intensidad(). Calcula la intensidad de luz de un estado.
ley_malus.py:
ley_malus(). Representacion de la intensidad de la luz al atravesar dos polarizadores lineales.
efecto_zenon.py:
nPolarizadores(). Producto de N polarizadores lineales.
efectoZenon(). Intensidad transmitida por un conjunto de N polarizadores.
Descarga de archivos:
Mdulo interactivo emanim12.py

81
PIMCD2013-python, Publicacin 1.0

Mdulo con las funciones principales polarizacion.py


Archivo con la descripcin de la ley de Malus ley_malus.py
Archivo con el ejemplo del efecto Zenn efecto_zenon.py

6.1 Introduccin

Desde un punto de vista clsico, la luz es una onda electromagntica constituida por dos campos, elctrico y
magntico oscilando normales a la direccin de propagacin y normalmente entre s. Bajo esta definicin se llama
polarizacin de la luz a la trayectoria del vector campo elctrico. Si la trayectoria de la luz es catica se dice que
la luz est despolarizada, as mismo si la trayectoria est bien definida hablamos de estados de polarizacin o
tambin llamados estados puros.
La polarizacin de la luz est intrnsecamente ligada al concepto de onda plana (ver seccin, Fuentes de luz-Onda
plana).

6.2 Programa interactivo para el anlisis de la polarizacin

Andras Szilagyi ha realizado un mdulo interactivo muy interesante para el anlisis de la polarizacion:
emanim12.py. Se puede encontrar en http://www.enzim.hu/~szia/emanim for more information.
En la siguiente Figura se muestra un ejemplo de utilizacin de este mdulo. Tiene un men y botones para selec-
cionar el tipo de anlisis de polarizacin y parmetros utilizados

Figura 6.1: Figura. Ejemplo de uso del programa enamin.py

6.3 Definiciones de polarizadores

La luz polarizada puede cambiar de estado al atravesar distintos elementos pticos. La caracterizacin y modelado
de estos medios resulta crtica en ptica. El clculo de Jones permite no solo definir estados de polarizacin sino

82 Captulo 6. Polarizacin
PIMCD2013-python, Publicacin 1.0

adems, representar los elementos pticos mediante matrices, tales que el vector de Jones a la salida del sistema
sea la accin de la matriz del medio sobre un vector de Jones.
Rotador
Un rotador es un sistema capaz de rotar el vector de Jones pero no modificar su estado. Por ello estn representados
por matrices de rotacin. Para su implementacin basta con definir la matriz
( )
cos sin
,
sin cos

def rotacion(theta = 0):


"""matriz de rotacion
- theta: angulo de rotacion
"""
#Definicion de la matriz
return sp.matrix(sp.array([[ cos(theta), sin(theta)],
[-sin(theta), cos(theta)]]), dtype = float)

Polarizador lineal
Los polarizadores lineales son elementos pticos tales que independientemente del estado de polarizacin a la
entrada transforman dicho estado en luz linealmente polarizada con acimut . Donde representa el ngulo del
eje del polarizador. La matriz de Jones de un polarizador lineal viene representada por

cos2
( )
sin cos
,
sin cos sin2

def polarizadorLineal(theta = 0):


"""Polarizador lineal
- theta: angulo de entrada en radianes
"""
#Metodo directo
#return sp.matrix(sp.array([[cos(theta) ** 2, sin(theta) * cos(theta)],
# [sin(theta) * cos(theta), sin(theta) ** 2]]), dtype = float)

PL=sp.matrix(sp.array([[1, 0], [0, 0]]), dtype = float)


return rotacion(-theta) * PL * rotacion(theta)

Polarizador Retardador
Un retardador lineal es un elemento ptico compuesto por un material birrefringente capaz de introducir un re-
tardo entre las componentes paralela y perpendicular de la luz incidente. Est constituido por dos ejes o tambin
llamadas lneas neutras con ndices de refraccin asociados ordinario y extraordinario, la orientacin de los ejes y
el espesor determinan la accin de la lmina sobre la luz incidente. El retardo se introduce fruto de la diferencia
de camino ptico asociada a cada eje. La matriz de Jones asociada a un retardador viene dada por

cos 2 + 2 cos 2 sin 2 sin 2


( )

sin 2 sin 2 cos 2 sin 2 cos 2

def polarizadorRetardador(desfase = 0, ne = 1, no = 1, d = 1 * um, wavelength = 0.6328 * um, theta


"""Retardador
Se puede calcular de dos formas. Si desfase es distinto de None, entonces es lo que man
Si desfase=None, entonces se calcula el desfase con el resto de cosas.
- desfase: desfase del rotador definido como 2*pi*(ne-no)*d/lambda
- ne: indice extraordinario, no: indice ordinario, d: espesor de la lamina, wavelength:
- theta: angulo de rotacion
"""
#Definicion del retardo
if desfase == None:
desfase = 2 * sp.pi * (ne - no) * d / wavelength

6.3. Definiciones de polarizadores 83


PIMCD2013-python, Publicacin 1.0

#Definicion de la matriz del retardador


Lretardo = sp.matrix(sp.array([[ 1, 0],
[ 0, sp.exp(1j * desfase)]]), dtype = complex)

return rotacion(-theta) * Lretardo * rotacion(theta)

Lmina Lambda/4
Las lminas retardadoras hacen uso de la birrefringencia de la luz. Una lmina de cuarto de onda introduce un
retardo de /2 entre las componentes del vector de Jones de la luz incidente sobre la lmina. La matriz de Jones
del retardador de cuarto de onda es
( )
1 + cos 2 sin 2
,
sin 2 1 cos 2

def laminaLambdaCuartos(theta = 0 * grados):


"""lamina lambda/4. Muy utilizada porque pasa de luz linealmente polarizada a luz circular
"""
#Definicion de la matriz
return polarizadorRetardador(desfase = sp.pi / 2, theta = theta)

Lmina Lambda/2
Las lminas de media onda, alteran el sentido de giro del vector luz, derechas a izquierda o viceversa. Por tanto
los estados linealmente polarizados son invariantes bajo estos elementos pticos, mientras que si se incide sobre
una lmina de media onda con luz circular a derechas, a la salida mantiene la circularidad pero el sentido de giro
ser levgiro. Idem para estados elpticamente polarizados. La matriz de Jones del retardador de media onda es
( )
cos 2 sin 2
,
sin 2 cos 2

def laminaLambdaMedios(theta = 0 * grados):


"""lamina lambda/2. Muy utilizada porque gira el estado de polarizacion
"""
#Definicion de la matriz
return polarizadorRetardador(desfase = sp.pi, theta = theta)

6.4 Definiciones de estados de luz polarizada

Considrese una onda plana monocromtica de frecuencia , vector de onda , y amplitud 0 representada como

= 0 + ,


= 0 + .

Es posible definir esta seal nicamente con la parte espacial. As denotando el desfase como = se
escribe
( )
0
= .
0

Este vector recibe el nombre de vector de Jones. Obsrvese como este vector representa la proyeccin trayectoria
del campo elctrico sobre un plano perpendicular a la direccin de propagacin. As se puede probar como el
conjunto de trayectorias posibles de acuerdo a estos vectores estn definidas por la ecuacin

2 2 cos
2 + 2 2 = sin2 .
0 0 0 0

84 Captulo 6. Polarizacin
PIMCD2013-python, Publicacin 1.0

Esta ecuacin representa una elipse, la llamada elipse de polarizacin y de ella derivan el conjunto de estados
puros. De este modo, si = con , entero, o si 0 = 0 o 0 = 0, la elipse de polarizacin degenera en una
recta, y se dice que el estado de la luz es linealmente polarizado, as mismo, si 0 = 0 y = /2, la elipse
degenera en una circunferencia, y por tanto la luz es circularmente polarizada. En cualquier otro caso distinto de
estos dos la luz se dice que posee polarizacin elptica.
Luz Lineal
Un vector de Jones unitario de luz linealmente polarizada es siempre de la forma
( )
cos
= .
sin

Donde representa el azimut del estado de luz, es decir, la inclinacin del vector campo elctrico. luzLineal
implementa este vector.
def luzLineal(alfa = 0):
"""Luz linealmente polarizada
- alfa, angulo en el cual esta polarizada
"""
#Definicion del vector de Jones
return sp.matrix([[ cos(alfa)], [sin(alfa)]])

Luz Circular
Bajo la condicin = /2 con 0 = 0 se obtienen los vectores de Jones
El doble signo denota el sentido de giro del vector campo elctrico, si es positivo, entonces la luz ser circularmente
polarizada a derechas o dextrgira. En caso contrario se dice que es circularmente polarizada a izquierdas o
levgira. La eleccin entre circular a derechas o izquierdas se especifica mediante una d o una i en el argumento
de la funcin luzCircular
def luzCircular(tipo = d):
"""Luz circularmente polarizada
- tipo, d: derecha i: izquierda
"""
#Definicion del vector de Jones a dextrogiro o levogiro
if tipo == d:
return sp.matrix([[1], [1j]]) / sp.sqrt(2)
elif tipo == i:
return sp.matrix([[1], [-1j]]) / sp.sqrt(2)

Luz Elptica
Si el vector de Jones no es ninguno de los dos casos anteriores, lineal o circular, entonces es necesariamente
elpticamente polarizado. Su definicin como funcin de Python debe emplear la forma ms general del vector de
Jones,
( )

.

def luzEliptica(a = 1, b = 1, desfase = 0, theta = 0):


"""Luz elipticamente polarizada
- a: amplitud de eje x
- b: amplitud de eje y
- desfase: desfase entre ambos ejes
- theta: rotacion del haz respecto de eje x
"""
#Definicion del vector de Jones
M = sp.matrix([[a], [b * sp.exp(1j * desfase)]], dtype = complex)
return rotacion(theta) * M

6.4. Definiciones de estados de luz polarizada 85


PIMCD2013-python, Publicacin 1.0

6.5 Clculo de la intensidad de un vector de polarizacin

La intensidad de la luz no es ms que el mdulo del vector de Jones. La funcin intensidad cumple este cometido
def intensidad(vectorPolarizacion):
#Calculo de la intensidad
return float(abs(vectorPolarizacion[0]) ** 2 + abs(vectorPolarizacion[1]) ** 2)

6.6 Polarizacin bsica

La polarizacin de la luz se puede ver afectada al atravesar esta distintos elementos pticos. El formalismo de Jones
constituye una representacin tanto de los elementos pticos, mediante matrices 2x2, como de estados puros de
polarizacin, mediante vectores. De este modo, el estado de polarizacin a la salida de un elemento ptico queda
determinado por la accin de la matriz de Jones del elemento sobre el vector de Jones que representa el estado de
polarizacin incidente.
As supnganse los siguientes ejemplos
Polarizador lineal
Un haz de luz linealmente polarizado segn el eje x incide sobre un polarizador cuyo eje est alineado con el eje
y. Obviamente no hay transmisin de luz, por ello el vector de Jones a la salida del polarizador debe ser el vector
nulo, y en consecuencia la intensidad de la luz es cero. En efecto
( ) ( ) ( )
0 0 1 0
=
0 1 0 0

Esto se programara de la siguiente forma:


PolarizadorLineal(90)*luzLineal(0)

Lamina de media de onda


Un haz de luz circularmente polarizado a derechas incide sobre una lmina de media onda cuyo eje rpido puede
estar aleatoriamente dispuesto, por sencillez supngase que est alineado con el eje de abscisas. El resultado de
este experimento es la obtencin de luz circularmente polarizada a izquierdas, como muestra el clculo:
laminaLambdaMedios(0)*luzCircular(d)

( ) ( ) ( )
1 0 1 1
=
0 1

Lmina de cuarto de onda


Un haz de luz linealmente polarizado segn el eje x incide sobre una lmina retardadora cuyo eje rpido est
inclinado 45 respecto de la horizontal. Probaremos como la luz a la salida del sistema es circularmente polarizada:
laminaLambdaCuartos(45)*luzLineal(0)

( ) ( ) ( )
1 1 1
=
1 0

6.7 Ley de Malus

La ley de Malus establece que la intensidad de la luz a la salida de un sistema de dos polarizadores es directamente
proporcional a cos2 siendo el ngulo comprendido entre los ejes de los polarizadores. La demostracin es
sencilla, basta considerar un estado de luz lineal incidiendo sobre un polarizador, y calcular el vector de Jones a

86 Captulo 6. Polarizacin
PIMCD2013-python, Publicacin 1.0

la salida, el mdulo cuadrado de este vector de Jones posee una dependencia directamente proporcional a cos2 .
Este hecho se muestra en el siguiente cdigo.
"""Ley de Malus"""
#Importamos modulos scipy, sys y polarizacion
import scipy as sp
import sys
sys.path.append(../)
from polarizacion import *

#Angulo entre los polarizadores


angulos = sp.linspace(0,2*sp.pi,100)
#Se predefine la intensidad para un bucle posterior
I= sp.zeros_like(angulos)

#haz incidente
haz=luzLineal(alfa=0*grados)
P1 = polarizadorLineal(theta = 0*grados)

#Calculo de la intensidad para cada angulo


for i in range(len(angulos)):
P2 = polarizadorLineal(theta = angulos[i])
vectorFinal = P2*P1*haz
I[i]=intensidad(vectorFinal)

#Representacion de la intensidad
plt.figure()
plt.plot(angulos/grados,I,k,lw=2)
plt.xlabel(r$\theta$ (grados),fontsize=24)
plt.ylabel(Intensidad transmitida,fontsize=24)
plt.xlim([0,angulos[-1]/grados])
plt.show()

1.0
Intensidad transmitida

0.8

0.6

0.4

0.2

0.00 50 100 150 200 250 300 350


(grados)
6.7. Ley de Malus 87
PIMCD2013-python, Publicacin 1.0

6.8 Efecto Zenon

El efecto Zenn es el paso de luz a travs de un sistema de polarizadores. Si bien se extingue la luz bajo cuando
dos polarizadores posicionan sus ejes perpendicularmente, bajo otros ngulos la luz atraviesa el sistema. As, si se
disponen N polarizadores con ngulo entre sus ejes 360/ aumentar la transmitancia al aumentar el nmero de
polarizadores.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#----------------------------------------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#----------------------------------------------------------------------
"""
Efecto Zenon, n polarizadores rotados igual entre si.
"""
import scipy as sp
import sys
sys.path.append(../)
from polarizacion import *

def nPolarizadores(N = 4):


#Define un sistema de una pila de N polarizadores

#Angulo de cada polarizador


angulos = sp.linspace(sp.pi / 2, 0, N)

#Definicion de la matriz del polarizador


M = polarizadorLineal(theta = angulos[0])
#Calculo de la matriz producto
for i in range(1, len(angulos)):
polarizador = polarizadorLineal(theta = angulos[i])
M = M * polarizador

#Vector de Jones a la salida del sistema de N polarizadores bajo incidencia de luz


#polarizada circular dextrogira
vectorFinal = M * luzCircular(tipo = d)
return intensidad(vectorFinal)

def efectoZenon(numMaxPolarizadores = 5):


#Numero de polarizadores
numPolarizadores = sp.array(range(2, numMaxPolarizadores + 1))
#Intensidad a la salida, se preinicializa con el zeros y posteriormente se calcula
intensidad = sp.zeros(len(numPolarizadores), dtype = float)
for i in range(len(numPolarizadores)):
intensidad[i] = nPolarizadores(N = numPolarizadores[i])

#Representacion de la intensidad
plt.figure()
plt.plot(numPolarizadores, intensidad, ko)
plt.xlabel(# polarizadores, fontsize = 20)
plt.ylabel($I_{transmitida}$, fontsize = 24)
plt.title(efecto zenon, fontsize = 24)

if __name__ == __main__:
efectoZenon(numMaxPolarizadores = 75)
plt.show()

88 Captulo 6. Polarizacin
PIMCD2013-python, Publicacin 1.0

0.5 efecto zenon

0.4
Itransmitida

0.3

0.2

0.1

0.00 10 20 30 40 50 60 70 80
# polarizadores

6.8. Efecto Zenon 89


PIMCD2013-python, Publicacin 1.0

90 Captulo 6. Polarizacin
CAPTULO 7

Interaccin radiacin-materia

Autor Luis Miguel Snchez Brea

Contenidos de este captulo:


Introduccin
Dipolo
Resonancia
Densidad espectral
Seccin eficaz

Herramientas utilizadas en este tutorial:


numpy: manipulacin de datos
scipy: Herramientas matemticas
Descarga de archivos:
Campo generado por un dipolo - modo dibujo dipolo.py
Campo generado por un dipolo - genera contornos dipolo_contour.py
Campo generado por un dipolo - modo animado dipolo_animado.py
Campo generado por un dipolo - modo video dipolo_video.py
Resonancia resonancia.py

7.1 Introduccin
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

import scipy as sp
import matplotlib.pyplot as plt

m = 1 #metros
kg = 1 #kilogramo
sg = 1 #segundos

V = 1 #voltio

91
PIMCD2013-python, Publicacin 1.0

C = 1 #culombios
Hz = 1 / sg #hertzio

nm = 1e-9 * m

qe = -1.602176565 * 10 ** -19 * C #carga del electron


me = 9.10938291 * 10 ** -31 * kg #masa del electron

def resonancia(E0 = 1000 * V / m, w0 = 1e15 * Hz, gamma = 1e8 * Hz):

""" (float, float) --> (complex)

- Descripcion: En la interaccion luz-atomo ligado un parametro esencial es el calc


de la distancia etre el electron y el nucleo, pues esto pr
que generara la radiacion dispersada.

- Precondicion: g<<w0

- Entradas:
* w0: frecuencia de resonancia
* gamma: amortiguamiento

- Salidas:
* r: distancia compleja
"""

#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia


n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)

#distancia electron-nucleo
r = (qe / me) * E0 / (w ** 2 - w0 ** 2 - 1.j * gamma * w)

#diversos dibujos

#distancia
plt.figure(figsize = (11, 9), facecolor = w, edgecolor = k)
plt.subplot(221)
plt.plot(w, abs(r) / nm, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($r\;(nm)$, fontsize = 18)

#desfase
plt.subplot(222)
plt.plot(w, sp.angle(r) * 180 / sp.pi, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($\phi \;(grados)$, fontsize = 18)

#parte real
plt.subplot(223)
plt.plot(w, sp.real(r), k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($Re(r)$, fontsize = 18)

#parte imaginaria
plt.subplot(224)
plt.plot(w, sp.imag(r), k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($Im(r)$, fontsize = 18)

92 Captulo 7. Interaccin radiacin-materia


PIMCD2013-python, Publicacin 1.0

resonancia(E0 = 1000 * V / m, w0 = 1e15 * Hz, gamma = 1e8 * Hz)


plt.tight_layout()

plt.show()

1.8 0
1.6 20
1.4 40
1.2 60

(grados)
r (nm)

1.0 80
0.8 100
0.6 120
0.4 140
0.2 160
0.00.0 0.5 1.0 1.5 2.0 1800.0 0.5 1.0 1.5 2.0
(Hz) 1e9+9.99999e14 (Hz) 1e9+9.99999e14

1.0 1e 9 0.0 1e 9
0.2
0.5 0.4
0.6
0.8
Im(r)
Re(r)

0.0
1.0
1.2
0.5 1.4
1.6
1.00.0 0.5 1.0 1.5 2.0 1.80.0 0.5 1.0 1.5 2.0
(Hz) 1e9+9.99999e14 (Hz) 1e9+9.99999e14

7.2 Dipolo

Una carga elctrica oscilante genera un campo electromagntico. En el caso de un movimiento sinusoidal de
frecuencia w, el campo generado resulta

3 2 2
= cos ( )()
4 ()3 ()2

3 1 1 ()
= sin ( )
4 ()3 ()2

= 0

Esto es lo que se ha programado en las siguientes figuras, para el caso de un plano y para un instante de tiempo
t=0.

7.2. Dipolo 93
PIMCD2013-python, Publicacin 1.0

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Emision del dipolo
#-------------------------------------

import scipy as sp
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm

um=1; mm=1000*um; m=1000*mm; s=1; fs=1e-15*s

wavelength=0.6328*um
k = 2 * sp.pi / wavelength
c= 299792.458 *m/s
w=c*k
q=1; r0=1; epsilon0=1; #normalizacion

#area de visualizacion
tamano=2.5*um
x=sp.linspace(-tamano/2, tamano/2, 250)
z=sp.linspace(-tamano/2, tamano/2, 250)
X,Z=sp.meshgrid(x, z)

#calculo de la intensidad
R = sp.sqrt(X** 2 + Z ** 2)
sinTheta=X/R

E_theta=q*r0*k**2/(4*sp.pi*R*epsilon0)*sinTheta*sp.cos((k*R))
intensidad = abs(E_theta) ** 2
intensidad=sp.log(intensidad+1)

#Se dibuja por primera vez


fig = plt.figure(1)
a = plt.subplot(111)
im = a.imshow(intensidad, cmap=cm.jet)
plt.show()

94 Captulo 7. Interaccin radiacin-materia


PIMCD2013-python, Publicacin 1.0

50

100

150

200

0 50 100 150 200

contourf contour
4 4

2 2

0 0

2 2

4 4
4 2 0 2 4 4 2 0 2 4

0.0 1.5 3.0 4.5 6.0 7.5 9.0 10.512.0 1.5 3.0 4.5 6.0 7.5 9.0 10.5

Como la fluctuacin es temporal, en los siguientes archivos se muestra este movimiento. Uno de ellos genera una

7.2. Dipolo 95
PIMCD2013-python, Publicacin 1.0

animacin y el otro un vdeo:

50

100

150

200

0 50 100 150 200

7.3 Resonancia

El efecto que tiene la luz sobre el movimiento de los electrones depende fuertemente de la frecuencia de la
onda electromagntica incidente en comparacin con la frecuencia de resonancia del electrn en el tomo. En la
siguiente figura se muestra cul es el desplazamiento mximo producido en el tomo en funcion de los parmetros
del tomo y de la frecuencia de la luz incidente.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: cp1252 -*- " Codigo para poder usar tildes"
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

from __future__ import division


import locale
locale.setlocale(locale.LC_NUMERIC, C)

import scipy as sp
import matplotlib.pyplot as plt

m = 1 #metros;
kg = 1 #kilogramo
sg = 1 #segundos
V = 1 #voltio
C = 1 #culombios

96 Captulo 7. Interaccin radiacin-materia


PIMCD2013-python, Publicacin 1.0

Hz = 1 / sg #hertzio
nm = 1e-9 * m
qe = -1.602176565 * 10 ** -19 * C #carga del electron
me = 9.10938291 * 10 ** -31 * kg #masa del electron

def resonancia(E0 = 1000 * V / m, w0 = 1e15 * Hz, gamma = 1e8 * Hz):


""" (float, float) --> (complex)
- Descripcion: En la interaccion luz-atomo ligado un parametro esencial es el calc
de la distancia entre el electron y el nucleo, pues esto produce el dipolo
que generara la radiacion dispersada.
- Precondicion: g<<w0
- Entradas: * w0: frecuencia de resonancia * gamma: amortiguamiento
- Salidas: * r: distancia compleja"""
#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia
n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)
#distancia electron-nucleo
r = (qe / me) * E0 / (w ** 2 - w0 ** 2 - 1.j * gamma * w)
#distancia
plt.figure(figsize = (11, 5), facecolor = w, edgecolor = k)
plt.subplot(121)
plt.plot(w, abs(r) / nm, k, linewidth = 2)
plt.title("r" , fontsize=24)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($r\;(nm)$, fontsize = 18)
#desfase
plt.subplot(122)
plt.plot(w, sp.angle(r) * 180 / sp.pi, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($\phi \;(grados)$, fontsize = 18)
plt.title("desfase" , fontsize=24)
return r

resonancia(E0 = 1000 * V / m, w0 = 1e15 * Hz, gamma = 1e8 * Hz)


plt.tight_layout()
plt.show()

1.8 r 0 desfase
1.6 20
1.4 40
1.2 60
(grados)
r (nm)

1.0 80
0.8 100
0.6 120
0.4 140
0.2 160
0.00.0 0.5 1.0 1.5 2.0 1800.0 0.5 1.0 1.5 2.0
(Hz) 1e9+9.99999e14 (Hz) 1e9+9.99999e14

7.3. Resonancia 97
PIMCD2013-python, Publicacin 1.0

7.4 Densidad espectral

la densidad de energa espectral, i.e, la cantidad de energa electromagntica por unidad espectral que llega por
unidad de superficie
2 /4
() = | |2 = ( ) ,
2 /4 + ( )2
donde es el campo a la salida del elemento difra, es la frecuencia de resonancia y es la frecuencia del haz
incidente
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: cp1252 -*- " Codigo para poder usar tildes"
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

from __future__ import division


import locale
locale.setlocale(locale.LC_NUMERIC, C)

import scipy as sp
import matplotlib.pyplot as plt

m = 1 #metros;
kg = 1 #kilogramo
sg = 1 #segundos
V = 1 #voltio
C = 1 #culombios
Hz = 1 / sg #hertzio
nm = 1e-9 * m
qe = -1.602176565 * 10 ** -19 * C #carga del electron
me = 9.10938291 * 10 ** -31 * kg #masa del electron
epsilon0=8.8541878176e-12
c=3e8*m/sg

def densidadEspectral(E0 = 1000 * V / m, w0 = 1e15 * Hz, gamma = 1e8 * Hz):


""" (float, float) --> (complex)

- Descripcion: En la interaccion luz-atomo ligado un parametro esencial es el calc


de la distancia entre el electron y el nucleo, pues esto produce el dipolo
que generara la radiacion dispersada.
- Precondicion: g<<w0
- Entradas: * w0: frecuencia de resonancia * gamma: amortiguamiento
- Salidas: * r: distancia compleja"""

#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia


n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)

#distancia electron-nucleo
J=epsilon0*c*abs(E0)**2/(gamma**2/4+(w-w0)**2)

#distancia
plt.figure(facecolor = w, edgecolor = k)
plt.plot(w, J, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($J(\omega)$, fontsize = 18)

98 Captulo 7. Interaccin radiacin-materia


PIMCD2013-python, Publicacin 1.0

densidadEspectral(E0 = 1000 * V / m, w0 = 1e15 * Hz, gamma = 1e8 * Hz)


plt.tight_layout()
plt.show()

1.2 1e 12

1.0

0.8
J ( )

0.6

0.4

0.2

0.00.0 0.5 1.0 1.5 2.0


(Hz) 1e9+9.99999e14

Este parmetro est relacionado con el espectro emitido por el tomo.

7.5 Seccin eficaz

Esta seccin eficaz de extincin la denotamos y su relacin con la potencia extrada es la siguiente

2 2
= =
|| ( 2 2 )2 + 2 2

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: cp1252 -*- " Codigo para poder usar tildes"
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

from __future__ import division


import locale
locale.setlocale(locale.LC_NUMERIC, C)

import scipy as sp
import matplotlib.pyplot as plt

7.5. Seccin eficaz 99


PIMCD2013-python, Publicacin 1.0

m = 1; kg = 1; s = 1; V = 1; C = 1; Hz = 1 / s
nm = 1e-9 * m
qe = -1.602176565e-19 * C #carga del electron
me = 9.10938291e-31 * kg #masa del electron
epsilon0=8.8541878176e-12
c= 299792458*m/s

def seccion_eficaz_extincion(w0 = 1e15 * Hz, gamma = 1e8 * Hz):


""" (float, float) --> (complex)
- Descripcion: En la interaccion luz-atomo ligado un parametro esencial es el calc
de la distancia entre el electron y el nucleo, pues esto produce el dipolo que generara la
- Precondicion: g<<w0: Entradas: * w0: frecuencia de resonancia * gamma: amo
- Salidas: * r: distancia compleja"""
#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia
n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)
#seccion eficaz
sigma=(qe**2/(me*c*epsilon0))*gamma*w**2/((w**2-w0**2)**2+w**2*gamma**2)
#distancia
plt.figure(facecolor = w, edgecolor = k)
plt.plot(w, sigma, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($\sigma(\omega)$, fontsize = 18)
plt.title("Seccion eficaz extincion", fontsize=24)
texto="radio = %4.4g m" %(sp.sqrt(sigma.max()/sp.pi))
plt.text(w.min(),sigma.max()/2,texto,fontsize=16)
plt.tight_layout()

def seccion_eficaz_scattering(w0 = 1e15 * Hz, gamma = 1e8 * Hz):


""" (float, float) --> (complex)
- Descripcion: En la interaccion luz-atomo ligado un parametro esencial es el calc
de la distancia entre el electron y el nucleo, pues esto produce el dipolo que generara la
- Precondicion: g<<w0: Entradas: * w0: frecuencia de resonancia * gamma: amo
- Salidas: * r: distancia compleja"""
#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia
n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)
#seccion eficaz
sigma_T=qe**4/(6*sp.pi*me**2*c**4*epsilon0**2)

sigma=sigma_T*w**4/((w**2-w0**2)**2+w**2*gamma**2)
#distancia
plt.figure(facecolor = w, edgecolor = k)
plt.plot(w, sigma, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel($\sigma(\omega)$, fontsize = 18)
plt.title("Seccion eficaz de scattering", fontsize=24)
texto="radio = %4.4g m" %(sp.sqrt(sigma_T/sp.pi))
plt.text(w.min(),sigma.max()/2,texto,fontsize=16)
plt.tight_layout()

seccion_eficaz_extincion(w0 = 1e15 * Hz, gamma = 1e8 * Hz)


seccion_eficaz_scattering(w0 = 1e15 * Hz, gamma = 1e8 * Hz)

plt.show()

100 Captulo 7. Interaccin radiacin-materia


PIMCD2013-python, Publicacin 1.0

1.0 1e 49 Seccion eficaz


0.8

0.6
()

0.4

0.2

0.00.0 0.5 1.0 1.5 2.0


(Hz) 1e15

7.5. Seccin eficaz 101


PIMCD2013-python, Publicacin 1.0

102 Captulo 7. Interaccin radiacin-materia


CAPTULO 8

ndice de refraccin: modelo microscpico

Autor Luis Miguel Snchez Brea

Contenidos de este captulo:


Introduccin
ndice de refraccin para cargas ligadas
Aproximacin de Sellmeier
Aproximacin de Cauchy
Frecuencia de plasma

Herramientas utilizadas en este tutorial:


numpy: manipulacin de datos
scipy: Herramientas matemticas
Descarga de archivos:
Ejemplo de interferencias con ondas planas resonancia.py
Ejemplo de interferencias con ondas planas indice_refraccion.py
Ejemplo de interferencias con ondas planas indice_cauchy.py
Ejemplo de interferencias con ondas planas indice_sellsmeier.py
Ejemplo de interferencias con ondas planas frecuencia_plasma.py

8.1 Introduccin

Los ejemplos que aqu se desarrollan son autocontenidos, es decir, no necesitan de libreras especificas excepto
las estndar. El objetivo de este tema es, por una parte, conocer la relacin entre el modelo microscpico clsico
de interaccin radiacin-materia con el ndice de refraccin. Asimismo, se pretende analizar diversas expresiones
analticas para el ndice de refraccin, conociendo las propiedades del ndice de refraccin tales como la absorcin
y la dispersin.
Se compara las definiciones macroscpica y microscpica de la polarizacin. La primera se calcula a travs las
ecuaciones macroscpicas de Maxwell.
P = 0 E ,
La segunda se calcula a partir de las trayectorias de los tomos analizadas en el tomo de Lorentz. Mediante esta
comparacin se obtiene una ecuacin para la constante dielctrica en funcin de los parmetros microscpicos:

1
P= E, .
=1

103
PIMCD2013-python, Publicacin 1.0

De esta forma se calcula la constante dielctrica



2

= 0 1 + ,
0 02 2

Como tambin es conocido, se puede obtener el ndice de refraccin a partir de la constante dielctrica


= .
0

8.2 ndice de refraccin para cargas ligadas

En el caso de que no haya cargas libres, es decir, que el medio sea dielctrico, el ndice de refraccin se puede
simplificar a

2

= 0 1 + ,
0 02 2

donde la sumatoria representa los distintos tipos de resonancias que existen en el material.
Sacando las partes real e imaginaria se puede obtener el ndice de refraccin y de absorcin.
2
2 (0, 2 )
= 1 + 2 2 )2 + 2 ,
20 (0

2
= 2 2 )2 + 2 2 .
20 (0

En el siguiente ejemplo se muestra el ndice de refraccin para dos ejemplos. En el primero se muestra el ndice
de refraccin debido solamente a una resonancia.
En el segundo ejemplo se muestra el ndice de refraccin cuando el medio tiene 3 resonancias. Se observa un
carcter acumulativo. Para bajas frecuencias, el ndice de refraccin no es la unidad, sino mayor, mientras que
para altas frecuencias, por encima de la resonancia, la luz no observa la materia y el ndice de refraccin es la
unidad.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

import scipy as sp
import matplotlib.pyplot as plt

m = 1; kg = 1; sg = 1; V = 1; C = 1;
Hz = 1 / sg; nm = 1e-9 * m

q=1.6021765e-19*C
m=9.109382911e-31*kg
epsilon0=8.8541878176e-12

def indice_refraccion(Nv=1e15, f=(0.5,), w0 = (1e15 * Hz,), gamma = (1e8 * Hz,)):

#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia

104 Captulo 8. ndice de refraccin: modelo microscpico


PIMCD2013-python, Publicacin 1.0

n_puntos = 1000
anchura = 20
w = sp.linspace(min(w0) - anchura * max(gamma), max(w0) + anchura * max(gamma), n_puntos)

#distancia electron-nucleo
n2=1

for fj, w0j, gammaj in zip(f,w0,gamma):


n2=n2+Nv*q**2/(m*epsilon0)*fj/(w0j**2-w**2-1j*w*gammaj)

nc=sp.sqrt(n2)
n=sp.real(nc)
kappa=sp.imag(nc)

plt.figure()
#parte real
plt.subplot(211)
plt.plot(w, n, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.xlim(max(0,w[0]),w[-1])
plt.ylabel($n$, fontsize = 18)
plt.grid(True)

#parte imaginaria
plt.subplot(212)
plt.plot(w, kappa, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.xlim(max(0,w[0]),w[-1])
plt.ylabel($\kappa$, fontsize = 18)
plt.grid(True)
plt.tight_layout()

#ejemplo de 1 resonancia
indice_refraccion(Nv=1e18, f=(1,), w0 = (1e13 * Hz,), gamma = (1e8 * Hz,))

#ejemplo con 2 resonancias


indice_refraccion(Nv=3e24, f=(0.33,0.33), w0 = (2e14 * Hz,4e14*Hz), gamma = (1e12 * Hz,1e12 * Hz))

#muchas resonancias
f=(0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1)
w0= sp.array([1.0,1.2,1.4,1.6,1.8,2.0,2.2,2.4,2.6,2.8])*4e14*Hz
gamma= sp.array([1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0])*1e13*Hz
indice_refraccion(Nv=1e26, f=f, w0 = w0, gamma = gamma)

plt.show()

8.2. ndice de refraccin para cargas ligadas 105


PIMCD2013-python, Publicacin 1.0

1.8
1.6
1.4
1.2
n

1.0
0.8
0.6
0.40.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0
(Hz) 1e9+9.998e12
1.2
1.0
0.8
0.6

0.4
0.2
0.00.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0
(Hz) 1e9+9.998e12

3.5
3.0
2.5
2.0
n

1.5
1.0
0.5
0.0 2.0 2.5 3.0 3.5 4.0
(Hz) 1e14
3.5
3.0
2.5
2.0

1.5
1.0
0.5
0.0 2.0 2.5 3.0 3.5 4.0
(Hz) 1e14

106 Captulo 8. ndice de refraccin: modelo microscpico


PIMCD2013-python, Publicacin 1.0

3.0
2.5
2.0
1.5
n

1.0
0.5
0.00.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4
(Hz) 1e15
2.0
1.5
1.0

0.5
0.00.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4
(Hz) 1e15

8.3 Aproximacin de Sellmeier

La ecuacin anteriormente descrita es interesante, pero a la hora de trabajar con ella es mejor realizar algn tipo
de aproximacin. En primer lugar porque en ptica se suele trabajar con longitudes de onda y no con frecuencias.
La segunda es para hacer casar las ecuaciones de la dispersin de materiales, conocidas previamente y utilizadas
en la ptica geomtrica.
Una de ellas es la ec. de Sellmeier.
2 2
2 () 1 = + + + ...
2 21 2 22

Se pueden encontrar los parmetros en muchas pginas web. Por ejemplo, hemos utilizado los siguientes materia-
les bastante comunes
Fused_Silica_B=(6.96166300E-01, 4.07942600E-01, 8.97479400E-01)
Fused_Silica_C=(4.67914826E-03, 1.35120631E-02, 9.79340025E01)

BK7_B=(1.03961212E00, 2.31792344E-01, 1.01046945E00)


BK7_C=(6.00069867E-03, 2.00179144E-02, 1.03560653E02)

MgF_B=(4.13440230E-01, 5.04974990E-01, 2.49048620E00)


MgF_C=(1.35737865E-03, 8.23767167E-03, 5.65107755E02)

Zafiro_B=(1.50397590E00, 5.50691410E-01, 6.59273790E00)


Zafiro_C=(5.48041129E-03, 1.47994281E-02, 4.02895140E02)

Veamos algunas de las grficas y el cdigo para programarlos. Este parmetro se denomina dispersin cromtica.

8.3. Aproximacin de Sellmeier 107


PIMCD2013-python, Publicacin 1.0

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

import scipy as sp
import matplotlib.pyplot as plt

wavelength=sp.linspace(0.4, 1 ,1000)

MgF_B=(4.13440230E-01, 5.04974990E-01, 2.49048620E00)


MgF_C=(1.35737865E-03, 8.23767167E-03, 5.65107755E02)

Zafiro_B=(1.50397590E00, 5.50691410E-01, 6.59273790E00)


Zafiro_C=(5.48041129E-03, 1.47994281E-02, 4.02895140E02)

Fused_Silica_B=(6.96166300E-01, 4.07942600E-01, 8.97479400E-01)


Fused_Silica_C=(4.67914826E-03, 1.35120631E-02, 9.79340025E01)

BK7_B=(1.03961212E00, 2.31792344E-01, 1.01046945E00)


BK7_C=(6.00069867E-03, 2.00179144E-02, 1.03560653E02)
print sp.sqrt(Zafiro_C)

#la longitud de onda debe ser en micras

#no es la definicion de clase sino wikipedia - que esta en otros

def indice_refraccion(wavelength, B,C):

i=2
n2=sp.zeros_like(wavelength)+1
for bi,ci in zip(B,C):
n2=n2+bi*wavelength**2/(wavelength**2-ci)

n=sp.sqrt(n2)
return n

def dibujar_n(wavelength,n, titulo=):


#diversos dibujos
plt.figure()
plt.plot(wavelength, n, k, linewidth = 2)
plt.xlabel($\lambda (\mu m)$, fontsize = 18)
plt.xlim(wavelength[0],wavelength[-1])
plt.ylabel($n$, fontsize = 18)
plt.title(titulo, fontsize=20)
plt.grid(True)

n=indice_refraccion(wavelength, BK7_B,BK7_C)
dibujar_n(wavelength,n,Sellmeier: BK7)

n=indice_refraccion(wavelength, Fused_Silica_B,Fused_Silica_C)
dibujar_n(wavelength,n,Sellmeier: Fused_Silica)

n=indice_refraccion(wavelength, Zafiro_B,Zafiro_C)

108 Captulo 8. ndice de refraccin: modelo microscpico


PIMCD2013-python, Publicacin 1.0

dibujar_n(wavelength,n,Sellmeier: Zafiro)

"""
#tambien se puede obtener el valor para 1 dato solo, sin dibujar
wavelength=0.5
n05=indice_refraccion(wavelength, BK7_B,BK7_C)
print "el indice de refraccion BK7 para %4.4f um es %4.6f" %(wavelength,n05)
"""

plt.show()

1.535 Sellmeier: BK7

1.530

1.525

1.520
n

1.515

1.510

1.5050.4 0.5 0.6 0.7 0.8 0.9 1.0


(m)

8.3. Aproximacin de Sellmeier 109


PIMCD2013-python, Publicacin 1.0

1.475 Sellmeier: Fused_Silica

1.470

1.465
n

1.460

1.455

1.4500.4 0.5 0.6 0.7 0.8 0.9 1.0


(m)

1.780 Sellmeier: Zafiro


1.775

1.770

1.765
n

1.760

1.755

1.750

1.7450.4 0.5 0.6 0.7 0.8 0.9 1.0


(m)
A partir de esta ecuacin se puede calcular el nmero de Abbe, que es un parmetro para calcular la dispersin del

110 Captulo 8. ndice de refraccin: modelo microscpico


PIMCD2013-python, Publicacin 1.0

material.

8.4 Aproximacin de Cauchy

Otra de las expresiones tpicas para ajustar el indice de refraccin con la longitud de onda es la ecuacin de
Cauchy,

() = + + 4 + ..
2

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

import scipy as sp
import matplotlib.pyplot as plt

m = 1; kg = 1; sg = 1; V = 1; C = 1;
Hz = 1 / sg; nm = 1e-9 * m; um=1e-6

q=1.6021765e-19*C
m=9.109382911e-31*kg
epsilon0=8.8541878176e-12

wavelength=sp.linspace(400*nm, 1000*nm,1000)

Fused_silica=(1.4580,0.00354*um**2)
Borosilicate_BK7=(1.5046,0.00420*um**2)
Hard_crown_K5=(1.5220,0.00459*um**2)
Barium_crown_BaK4 =(1.5690,0.00531*um**2)
Barium_BaF10=(1.6700,0.00743*um**2)
Dense_flint_SF10=(1.7280,0.01342*um**2)

def indice_refraccion(wavelength, param):


i=0
n=sp.zeros_like(wavelength)
for letra in param:
n=n+letra/wavelength**i
i=i+2
return n

def dibujar_n(wavelength,n, titulo=):


plt.figure()
plt.plot(wavelength/nm, n, k, linewidth = 2)
plt.xlabel($\lambda (nm)$, fontsize = 18)
plt.xlim(wavelength[0]/nm,wavelength[-1]/nm)
plt.ylabel($n$, fontsize = 18)
plt.title(titulo, fontsize=20)
plt.grid(True)

#ejemplo de 1 resonancia
n=indice_refraccion(wavelength, Fused_silica)
dibujar_n(wavelength,n, titulo=Cauchy: Fused_silica)

8.4. Aproximacin de Cauchy 111


PIMCD2013-python, Publicacin 1.0

n=indice_refraccion(wavelength, Borosilicate_BK7)
dibujar_n(wavelength,n, titulo=Cauchy: Borosilicate_BK7)

"""
wavelength=0.5
n05=indice_refraccion(wavelength,Borosilicate_BK7)
print "el indice de refraccion BK7 para %4.4f um es %4.6f" %(wavelength,n05)
"""

plt.show()

1.485 Cauchy: Fused_silica

1.480

1.475
n

1.470

1.465

1.460400 500 600 700 800 900 1000


(nm)

112 Captulo 8. ndice de refraccin: modelo microscpico


PIMCD2013-python, Publicacin 1.0

1.535 Cauchy: Borosilicate_BK7

1.530

1.525

1.520
n

1.515

1.510

1.505400 500 600 700 800 900 1000


(nm)

8.5 Frecuencia de plasma

En los medios conductores tenemos cargas ligadas (electrones internos) y cargas libres. Sin embargo, stos ltimos
son los que ms afectan al ndice de refraccin. Por ello, suponemos que slo hay cargas libres. La ecuacin de
ndice de refraccin se simplifica a

2 1
2 = 1 .
0 ( + )

Esta expresin se puede aproximar a

2
2 () 1 .
2
donde

2
=
0

Veamos algunos ejemplos con la expresin sin simplificar:


#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Frecuencia del plasma
#-------------------------------------

8.5. Frecuencia de plasma 113


PIMCD2013-python, Publicacin 1.0

import scipy as sp
import matplotlib.pyplot as plt

m = 1; kg = 1; sg = 1; V = 1; C = 1;
Hz = 1 / sg; nm = 1e-9 * m; um=1e-6

q=1.6021765e-19*C; m=9.109382911e-31*kg
epsilon0=8.8541878176e-12; c=299792458*m/sg

def indice_refraccion(w, Nv, gamma):


nc2=1-Nv*q**2/(m*epsilon0*w*(w+1j*gamma))
nc=sp.sqrt(nc2)
return nc

def dibujar_n(w,nc, wp=0):


plt.figure()
n=sp.real(nc)
kappa=sp.imag(nc)

plt.subplot(211) #parte real

plt.plot(w, n, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.xlim(w[0],w[-1])
plt.ylabel($n$, fontsize = 18)
plt.grid(True)

plt.subplot(212) #parte imaginaria


plt.plot(w, kappa, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.xlim(w[0],w[-1])
plt.ylabel($\kappa$, fontsize = 18)
plt.grid(True)

if wp>0:
plt.subplot(211)
plt.axvline(x=wp, ymin=0, ymax=1, lw=2, color=k, linestyle=--)
plt.subplot(212)
plt.axvline(x=wp, ymin=0, ymax=1, lw=2, color=k, linestyle=--)

plt.tight_layout()

def ejemplo(Nv,gamma):
wp=sp.sqrt(Nv*q**2/(m*epsilon0))
""" print "la frecuencia de resonancia es %4.6g" %(wp)
print "la longitud de onda de resonancia es %4.6g" %(2*sp.pi*c/wp)"""
w=sp.linspace(wp/4,wp*4,1000)
nc=indice_refraccion(w, Nv,gamma)
dibujar_n(w,nc,wp)

ejemplo(Nv=1e25, gamma=1e12)
ejemplo(Nv=1e25, gamma=1e14)
plt.show()

114 Captulo 8. ndice de refraccin: modelo microscpico


PIMCD2013-python, Publicacin 1.0

1.0
0.8
0.6
n

0.4
0.2
0.0 1 2 3 4 5 6 7
(Hz) 1e14
4.0
3.5
3.0
2.5
2.0

1.5
1.0
0.5
0.0 1 2 3 4 5 6 7
(Hz) 1e14

1.6
1.4
1.2
1.0
n

0.8
0.6
0.4 1 2 3 4 5 6 7
(Hz) 1e14
2.0
1.5
1.0

0.5
0.0 1 2 3 4 5 6 7
(Hz) 1e14

8.5. Frecuencia de plasma 115


PIMCD2013-python, Publicacin 1.0

116 Captulo 8. ndice de refraccin: modelo microscpico


CAPTULO 9

Ecuaciones de Fresnel

autor Luis Miguel Snchez Brea


revisor Jos Luis Vilas Prieto

Contenidos de este captulo:


Introduccin
Funciones para calcular las ecuaciones de Fresnel
Clculo de los coeficientes de Fresnel: medios dielctricos
Clculo de la transmitancia y reflectancia: medios dielctricos
Clculo de los coeficientes de Fresnel: medios absorbentes
Clculo de la transmitancia y reflectancia: medios absorbentes
Funciones de dibujo
Ejemplos
Calculo de los coeficientes de fresnel
Interfaz aire-vidrio
Interfaz vidrio-aire
Interfaz aire-metal
Ejercicios
Referencias

Herramientas utilizadas en este tutorial:


scipy: manipulacin de arrays de datos
matplotlib.pyplot: generacin de dibujos similar a Matlab
Archivos necesarios para las ecuaciones de Fresnel:
fresnel.py. Archivo con las funciones principales fresnel.py
Contenidos de los archivos:
fresnel.py:
coeficientesFresnel_dielectricos(). Calcula los coeficientes de Fresnel rs, rp, ts y tp
para medios dielctricos.
reflectancia_transmitancia_dielectricos(). Calcula las reflectancias y transmitan-
cias R_perp, R_par, T_perp, T_par para medios dielctricos
coeficientesFresnel_complejo(). Calcula los coeficientes de Fresnel rs, rp, ts y tp para
medios absorbentes.
reflectancia_transmitancia_complejo(). Calcula las reflectancias y transmitancias
R_perp, R_par, T_perp, T_par para medios absorbentes.
dibujarCoeficientes(). Dibuja los coeficientes rs, rp, ts y tp.
dibujarTransmitancias(). Dibuja los coeficientes R_perp, R_par, T_perp, T_par.

117
PIMCD2013-python, Publicacin 1.0

Descarga de archivos:
fresnel.py. Archivo con las funciones principales fresnel.py
fresnel_aire_vidrio.py. Archivo con el ejemplo del del calculo de la amplitud, fase e intensidad
de las componentes paralela y perpendicular en una intercara aire-vidrio fresnel_aire_vidrio.py
fresnel_vidrio_aire.py. Archivo con el ejemplo del del calculo de la amplitud, fase e intensidad
de las componentes paralela y perpendicular en una intercara aire-vidrio fresnel_vidrio_aire.py
fresnel_aire_metal.py. Archivo con el ejemplo del del calculo de la amplitud, fase e intensidad de
las componentes paralela y perpendicular en una intercara aire-vidrio fresnel_aire_metal.py

9.1 Introduccin

Las ecuaciones de Fresnel permiten calcular los campos transmitido y reflejado cuando una onda armnica plana
incide sobre una interfaz entre dos medios con ndice de refraccin distinto. Tienen una dependencia del estado
de polarizacin del haz incidente (paralelo al plano de incidencia, perpendicular al plano de incidencia o una
combinacin), de los ndices de refraccin del medio de entrada y de salida (1 , 2 ) y del ngulo de incidencia .
El ngulo del haz transmitido se obtiene a travs de la ley de Snell: 1 ( ) = 2 ( ).
Dichos campos reflejados y transmitido son lineales con el campo incidente y los coeficientes de proporcionalidad
son los coeficientes de fresnel. Para el caso de los campos reflejados

= * ,

= * ,

y para los campos transmitidos



= * ,

= * .

Un anlisis riguroso de cmo calcular dichos coeficientes de Fresnel a partir de las ecuaciones de Maxwell se
pueden encontrar en el libro de Cabrera 1 (captulos 9 y 10). Para el caso de que los dos medios sean dielctricos
estas ecuaciones resultan ser
2 ( ) 1 ( )
= ,
2 ( ) + 1 ( )

1 ( ) 2 ( )
= ,
1 ( ) + 2 ( )

y para los campos transmitidos

2 1 ( )
= ,
2 ( ) + 1 ( )

2 1 ( )
= .
1 ( ) + 2 ( )

Para el caso de que uno de los medios tenga ndice de refraccin comlejo, es decir sea un medio absorbente,
entonces las ecuaciones son algo ms complicadas. Se pueden encontrar en el libro de Cabrera 1 , captulo 9.
1 J.M. Cabrera, F.J. Lpez, F. Agull Lpez ; ptica Electromagntica: Fundamentos; Addison-Wesley (2001) ISBN 9788478290215

118 Captulo 9. Ecuaciones de Fresnel


PIMCD2013-python, Publicacin 1.0

9.2 Funciones para calcular las ecuaciones de Fresnel

En el archivo fresnel.py se han implementado las funciones que permiten el clculo de los coeficientes y las
reflectancias. Dichas funciones tienen la entrada de los ndices de refraccin n1, n2 y de un array de nmeros
que representan el ngulo de incidencia. La salida de estas funciones son: r_perp, r_par, t_perp, t_par cuando se
calculan coeficientes y R_perp, R_par, T_perp, T_par cuando se calculan reflectancias o transmitancias. Estos
parmetros los aceptan las funciones para dibujar.
La variable theta_i puede ser un nmero o un array generado con numpy. De esta forma se simplifican las repre-
sentaciones y se acelera enormemente el tiempo de clculo. Por consiguiente, las funciones de clculo devuelven
un array para los coeficientes , , y cuyo tamao es igual al .

9.2.1 Clculo de los coeficientes de Fresnel: medios dielctricos

El clculo de los coefientes de Fresnel en medios dielctricos se ha implementado, y es mostrado en el siguiente


extracto de cdigo. Para ello se ha creado la funcin coeficientesFresnel_dielectricos e introducido
las ecuaciones de Fresnel de los coeficientes de reflexin y transmisin para ls variables de entrada del ngulo de
incidencia y los ndices de refraccin del medio y del material dielctrico.
def coeficientesFresnel_dielectricos(n1, theta_i, n2):
#
# Calcula las componentes rs, rp, ts y tp mediante las eq. de Fresnel
# solamente se pueden admitir medios dielectricos, es decir indices de refraccion reales.
# Las ecuaciones programadas estan en Cabrera pagina 262

#ley de sell para conseguir theta_t


theta_t=sp.arcsin(n1*sin(theta_i)/n2)

#Precalculo para acelerar los calculos


cos_i=cos(theta_i)
cos_t=cos(theta_t)

#Coeficientes de Fresnell
r_par=(n2*cos_i-n1*cos_t)/(n2*cos_i+n1*cos_t)
r_perp=(n1*cos_i-n2*cos_t)/(n1*cos_i+n2*cos_t)
t_par=(2*n1*cos_i)/(n2*cos_i+n1*cos_t)
t_perp=(2*n1*cos_i)/(n1*cos_i+n2*cos_t)

return r_perp, r_par, t_perp, t_par

9.2.2 Clculo de la transmitancia y reflectancia: medios dielctricos

Definidos los coeficientes de Fresnel se puede calcular la transmitancia y la reflectancia entendiendo estas magni-
tudes como la relacin entre la intensidad reflejada o transmitida y la intensidad del haz incidente(ms detalles en
1
). As estos parmetros pueden ser derivados de los coeficientes de Fresnell como se muestra en el cdigo a partir
de la funcin reflectancia_transmitancia_dielectricos.
def reflectancia_transmitancia_dielectricos(n1, theta_i, n2):
""""Cabrera. pag 266"""
#Se calculan lo coeficientes de Fresnel
r_perp, r_par, t_perp, t_par= coeficientesFresnel_dielectricos(n1, theta_i, n2)

#Ley de sell para conseguir theta_t


theta_t=sp.arcsin(n1*sin(theta_i)/n2)

#acelera los calculos


cos_i=cos(theta_i)
cos_t=cos(theta_t)

9.2. Funciones para calcular las ecuaciones de Fresnel 119


PIMCD2013-python, Publicacin 1.0

#calculo de transmitancia y reflectancia


R_perp=abs(r_perp)**2
R_par=abs(r_par)**2
T_perp=abs(t_perp)**2*(n2*cos_t)/(n1*cos_i)
T_par=abs(t_par)**2*(n2*cos_t)/(n1*cos_i)

return R_perp, R_par, T_perp, T_par

9.2.3 Clculo de los coeficientes de Fresnel: medios absorbentes

Los medios absorbentes se caracterizan por tener un ndice de refraccin complejo. Nuevamente las relaciones de
Fresnel permiten determinar los coeficientes de transmisin y reflexin.
def coeficientesFresnel_complejo(n1, theta_i, n2c):
"""
Calcula las componentes rs y rp mediante las eq. de Fresnel
n^=n-ik
ejemplo:
theta_i=sp.linspace(0*grados,90*grados,10),

Los parametros de entrada pueden ser arrays de numeros.


Para dibujarlos el array debe ser theta_i
n2c puede ser complejo
"""
#Precalculos
kiz=cos(theta_i)
ktcz=sp.sqrt(n2c**2-n1**2*sin(theta_i)**2)
ktc2= n2c**2
ki2 = n1**2

#Calculo de los coeficientes de Fresnel


r_perp= (kiz-ktcz)/(kiz+ktcz)
t_perp= 2*kiz/(kiz+ktcz)
r_par= (kiz*ktc2-ktcz*ki2)/(kiz*ktc2+ktcz*ki2)
t_par= 2*kiz*ktc2/(kiz*ktc2+ktcz*ki2)

theta_i = theta_i/ grados

return r_perp, r_par, t_perp, t_par

9.2.4 Clculo de la transmitancia y reflectancia: medios absorbentes

En general la intensidad de la onda incidente no es la superposicin de la transmitida y la refleja-


da, sino que el material posee una cierta capacidad de absorcin de la radiacin. As, la suma de
la absorbancia, la reflectancia y la transmitancia es la unidad conservndose la energa. La funcin
reflectancia_transmitancia_complejo permite calcular la transmitancia y reflectancia.
def reflectancia_transmitancia_complejo(n1, theta_i, n2c):
"""
Calcula las componentes rs y rp mediante las eq. de Fresnel
n^=n-ik
ejemplo:
theta_i=sp.linspace(0*grados,90*grados,10),

Los parametros de entrada pueden ser arrays de numeros.


Para dibujarlos el array debe ser theta_i
n2c puede ser complejo
"""
#Coeficientes de Fresnel
r_perp, r_par, t_perp, t_par = coeficientesFresnel_complejo(n1, theta_i, n2c)

120 Captulo 9. Ecuaciones de Fresnel


PIMCD2013-python, Publicacin 1.0

#Reflectancia
R_perp=abs(r_perp)**2
R_par=abs(r_par)**2
#Precalculo
kiz=cos(theta_i)
ki2 = n1**2
ktcz=sp.sqrt(n2c**2-n1**2*sin(theta_i)**2)
ktc2=n2c**2
n2R=sp.real(n2c)
kappa2=sp.imag(n2c)
B=n2R**2-kappa2**2-n1**2*sin(theta_i)**2
ktz=sp.sqrt(0.5*(B+sp.sqrt(B**2+4*n2R**2*kappa2**2)))
#Transmitancias
T_perp=ktz*abs(t_perp)**2/kiz
T_par=ki2*sp.real(ktcz/ktc2)*abs(t_par)**2/kiz

return R_perp, R_par, T_perp, T_par

9.2.5 Funciones de dibujo

Hasta el moemnto se han implementado fisntintas funciones que permiten determinar los coeficientes de Fres-
nel en funcin del ngulo del haz incidente y de los ndices de refraccin del medio y del material. En es-
te epgrafe, se pretende definir una funcin de debujo capaz de dibujar los coeficientes de Fresnel en fun-
cin de . Los datos que dibuja son los resultantes de coeficientesFresnel_dielectricos() o de
coeficientesFresnel_complejo().
def dibujarCoeficientes(n1, theta_i, n2, r_perp, r_par, t_perp, t_par, nombreArchivo = ):
"""
Dibuja las ecuaciones de fresnel en funcion del angulo de entrada
"""
#Generacion della figura
plt.figure(figsize=(12,6))

#Amplitud
plt.subplot(1,2, 1)
plt.plot(theta_i / grados, abs(r_perp)*sp.sign(r_perp) , k--, lw = 2,\
label = u"$r_{\perp}$")
plt.plot(theta_i / grados, abs(r_par)*sp.sign(r_par) , k, lw = 2,\
label = u"$r_{\parallel}$")
plt.plot(theta_i / grados, abs(t_perp)*sp.sign(t_perp) , r--, lw = 2,\
label = r"$t_{\perp}$")
plt.plot(theta_i / grados, abs(t_par)*sp.sign(t_par) , r, lw = 2,\
label = r"$t_{\parallel}$")
#Leyenda de los ejes
plt.xlabel(r"$\phi (grados)$", fontsize = 22)
plt.ylabel(r"$Amplitud$", fontsize = 22)
plt.ylim(-1., 2.01)
plt.legend(loc=2,prop={size:18})

#Fase
plt.subplot(1,2, 2)
plt.plot(theta_i / grados, sp.unwrap(sp.angle(r_perp),2*sp.pi), k--, lw = 2,\
label = r"$r_{\perp}$")
plt.plot(theta_i / grados, sp.unwrap(sp.angle(r_par),2*sp.pi), k, lw = 2,\
label = r"$r_{\parallel}$")
plt.plot(theta_i / grados, sp.unwrap(sp.angle(t_perp),2*sp.pi), r--, lw = 2,\
label = r"$t_{\perp}$")
plt.plot(theta_i / grados, sp.unwrap(sp.angle(t_par),2*sp.pi), r, lw = 2,\
label = r"$t_{\parallel}$")
#Leyenda de los ejes
plt.xlabel(r"$\phi (grados)$", fontsize = 22)

9.2. Funciones para calcular las ecuaciones de Fresnel 121


PIMCD2013-python, Publicacin 1.0

plt.ylabel(r"$fase$", fontsize = 22)


#plt.ylim(-sp.pi - 0.01, sp.pi + 0.01)
plt.legend(loc=2,prop={size:18})

if not nombreArchivo == :
plt.savefig(nombreArchivo, dpi = 100, bbox_inches = tight, pad_inches = 0.1)

La funcin que dibuja la reflectancia y transmitancia es


def dibujarTransmitancias(n1, theta_i, n2, R_perp, R_par, T_perp, T_par, nombreArchivo = ):
"""
Dibuja las ecuaciones de fresnel en funcion del angulo de entrada
"""
#Generacion de la figura
plt.figure()
#dibujo
plt.subplot(1, 1, 1)
plt.plot(theta_i / grados, abs(R_perp) , k--, lw = 2, label = u"$R_{\perp}$")
plt.plot(theta_i / grados, abs(R_par) , k, lw = 2, label = u"$R_{\parallel}$")
plt.xlabel(r"$\phi (grados)$", fontsize = 22)
plt.ylabel(r"$Amplitud$", fontsize = 22)
plt.ylim(-0.01, 1.01)
plt.plot(theta_i / grados, abs(T_perp) , r--, lw = 2, label = r"$T_{\perp}$")
plt.plot(theta_i / grados, abs(T_par) , r, lw = 2, label = r"$T_{\parallel}$")
plt.xlabel(r"$\phi (grados)$", fontsize = 22)
plt.ylabel(r"$I$", fontsize = 22)
plt.ylim(-0.01, 1.01)
plt.legend(loc=3,prop={size:18})

if not nombreArchivo == :
plt.savefig(nombreArchivo, dpi = 100, bbox_inches = tight, pad_inches = 0.1)

9.3 Ejemplos

Los ejemplos de utilizacin del archivo fresnel.py se presentan en el archivo fresnel_ejemplos.py.


Como se puede observar en el cdigo siguiente, con muy poco cdigo se obtienen los ejemplos, pues simple-
mente es necesario declarar los parmetros, calcular los coeficientes y dibujar. Todas estas funciones ya han sido
desarrolladas previamente.

9.3.1 Calculo de los coeficientes de fresnel

El el siguiente ejemplo se muestra cmo llamar a la funcin coeficientesFresnel_dielectricos para


un nico valor de los parmetros
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#----------------------------------------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#----------------------------------------------------------------------
"""
ejemplos para las ecuaciones de Fresnel
"""
#Paquetes
import sys
sys.path.append(../)
from fresnel import * #@UnusedWildImport

122 Captulo 9. Ecuaciones de Fresnel


PIMCD2013-python, Publicacin 1.0

def coeficientes():
"interfaz aire-vidrio"
#Coeficientes de Fresnel para un caso particular
r_perp, r_par, t_perp, t_par = coeficientesFresnel_dielectricos(n1 = 1.5,\
theta_i = 45 * grados, n2 = 1.0)
#Muestra de resultados
print "coeficientes de reflexion paralelo: r_par= (%2.4f,%2.4f)" % (r_par.real,\
r_par.imag)
print "coeficientes de reflexion perpendicular: r_perp= (%2.4f,%2.4f)" % (r_perp.real,\
r_perp.imag)
print "coeficientes de transmision paralelo: t_par= (%2.4f,%2.4f)" % (t_par.real,\
t_par.imag)
print "coeficientes de transmision perpendicular: t_perp= (%2.4f,%2.4f)" % (t_perp.real,\
t_perp.imag)

if __name__ == __main__:
coeficientes()

Se supone la propagacin de un haz en aire, que incide a 45 grados sobre un vidrio dielctrico con ndice 1.5. As,
el resultado es:
>> coeficientes de reflexion paralelo: r_par= (0.2800,-0.9600)
>> coeficientes de reflexion perpendicular: r_perp= (0.8000,-0.6000)
>> coeficientes de transmision paralelo: t_par= (1.9200,-1.4400)
>> coeficientes de transmision perpendicular: t_perp= (1.8000,-0.6000)

9.3.2 Interfaz aire-vidrio

En este ejemplo se considera la incidencia de un haz de luz en el aire sobre una superficie de vidrio con ndice
1.5. Se representan la amplitud transmitida y reflejada, as como la fase reflejada en funcin del ngulo de inci-
dencia. Como se puede ver en las curvas de amplitud, la transmitancia paralela y perpendicular son relativamente
similares. Si se representan las transmitancias y reflectancias, se observa que cuando la reflectancia es mnima la
transmitancia es mxima. Relacin lgica puesto que R+T=1. No obstante es de especial inters este extremal,
llamandose ngulo de Brewster a aquel para el que la reflectancia es mnima. As se observa que la fase cambia
radicalmente en dicho punto, y la luz reflejada resulta perfectamente polarizada.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#----------------------------------------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#----------------------------------------------------------------------
"""
ejemplos para las ecuaciones de Fresnel
"""
#Carga de paquetes
import sys
sys.path.append(../)
from fresnel import * #@UnusedWildImport

def fresnel_aire_vidrio():
"interfaz aire-vidrio"
n1 = 1.
n2 = 1.5
theta_i = sp.linspace(0 * grados, 90 * grados, 500)

#se calculan los coeficientes de Fresnel para un array


r_perp, r_par, t_perp, t_par = coeficientesFresnel_dielectricos(n1 = n1,\
theta_i = theta_i, n2 = n2)
dibujarCoeficientes(n1, theta_i, n2, r_perp, r_par, t_perp, t_par)

9.3. Ejemplos 123


PIMCD2013-python, Publicacin 1.0

#Transmitancia y reflectancia
R_perp, R_par, T_perp, T_par= reflectancia_transmitancia_dielectricos(n1, theta_i, n2)
dibujarTransmitancias(n1, theta_i, n2, R_perp, R_par, T_perp, T_par)

if __name__ == __main__:
fresnel_aire_vidrio()
plt.show()

2.0 3.5
r r
1.5 r 3.0 r
t t
2.5
1.0 t t
Amplitud

2.0

fase
0.5
1.5
0.0
1.0

0.5 0.5

1.00 10 20 30 40 50 60 70 80 90 0.00 10 20 30 40 50 60 70 80 90
(grados) (grados)

1.0

0.8

0.6
I

0.4
R
R
0.2
T
T
0.0
0 10 20 30 40 50 60 70 80 90
(grados)

124 Captulo 9. Ecuaciones de Fresnel


PIMCD2013-python, Publicacin 1.0

9.3.3 Interfaz vidrio-aire

Este ejemplo es el contrario al anterior, se supone un haz de luz propagandose en vidrio, y se analiza el comporta-
miento del haz a la salida del material. Nuevamente se observa la reflexin de Brewster en un ngulo cercano a los
40 grados, y como cerca de este la transmitancia cambia abruptamente hasta el punto que nicamente se produce
reflexin del haz.
def fresnel_vidrio_aire():
"interfaz vidrio-aire"
n1 = 1.5
n2 = 1.
theta_i = sp.linspace(0 * grados, 90 * grados, 500)

#Se calculan los coeficientes de Fresnel para un array


r_perp, r_par, t_perp, t_par = coeficientesFresnel_complejo(n1 = n1,\
theta_i = theta_i, n2c = n2)
dibujarCoeficientes(n1, theta_i, n2, r_perp, r_par, t_perp, t_par)
#Reflectancia y transmitancia
R_perp, R_par, T_perp, T_par= reflectancia_transmitancia_complejo(n1, theta_i, n2)
dibujarTransmitancias(n1, theta_i, n2, R_perp, R_par, T_perp, T_par)

2.0 4
r r
3
1.5 r r
t 2 t
1.0 t t
1
Amplitud

fase

0.5 0

1
0.0
2
0.5
3

1.00 10 20 30 40 50 60 70 80 90 40 10 20 30 40 50 60 70 80 90
(grados) (grados)

9.3. Ejemplos 125


PIMCD2013-python, Publicacin 1.0

1.0

0.8

0.6
I

0.4
R
R
0.2
T
T
0.0
0 10 20 30 40 50 60 70 80 90
(grados)
9.3.4 Interfaz aire-metal

Los metales se caracterizan por tener un ndice de refraccin complejo siendo negativa la parte imaginaria del
mismo. As se supone la incidence de un haz sobre una intercara aire-metal, con ndice de refraccin = 0,769
6,08. Es destacable como la variacin en la fase de la componente paralela, es prcticamente invariante bajo
cambios en el ngulo de incidencia.
def fresnel_aire_metal():
"interfaz aire-metal"
n1 = 1.
#el metal se introduce con numero complejo cuya parte imaginaria es negativa
n2c = 0.769 - 6.08j
theta_i = sp.linspace(0 * grados, 90 * grados, 500)

#se calculan los coeficientes de Fresnel para un array


r_perp, r_par, t_perp, t_par = coeficientesFresnel_complejo(n1, theta_i, n2c)
dibujarCoeficientes(n1, theta_i, n2c, r_perp, r_par, t_perp, t_par)
#Reflectancia y transmitancia
R_perp, R_par, T_perp, T_par= reflectancia_transmitancia_complejo(n1, theta_i, n2c)
dibujarTransmitancias(n1, theta_i, n2c, R_perp, R_par, T_perp, T_par)

126 Captulo 9. Ecuaciones de Fresnel


PIMCD2013-python, Publicacin 1.0

2.0 4
r r
3
1.5 r r
t 2 t
1.0 t t
1
Amplitud

fase
0.5 0

1
0.0
2
0.5
3

1.00 10 20 30 40 50 60 70 80 90 40 10 20 30 40 50 60 70 80 90
(grados) (grados)

1.0

0.8

0.6
I

0.4
R
R
0.2
T
T
0.0
0 10 20 30 40 50 60 70 80 90
(grados)
9.4 Ejercicios

Determinar el valor de la reflectancia y transmitancia en incidencia normal cuando el medio incidente es el


vaco (n=1) y el segundo medio es aluminio.
Hacer una funcin para dibujar los coeficientes de reflexin y transmisin cuando un haz incide de forma
normal desde el vaco sobre un medio dielctrico cuyo ndice de refraccin vara entre 1 y 2.
Calcular mediante una grfica para qu ngulo hay un mnimo de Reflectancia en la componente paralela

9.4. Ejercicios 127


PIMCD2013-python, Publicacin 1.0

en el oro (se puede mirar su ndice de refraccin en la wikipedia).


Sea un haz policromtico entre 400 nm y 600 nm que incide sobre un medio dispersivo en el vacio. El ndice
de refracin es n(lambda)=1.5-0.1/lambda. Representar las transmitancias para 400,450,500,550 y 600 nm
en una misma grfica.

9.5 Referencias

128 Captulo 9. Ecuaciones de Fresnel


CAPTULO 10

Pulsos de luz

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto
Desde el punto de vista docente, muchos de los aspectos pticos se tratan con ondas armnicas planas, que tienen
una extensin espacio-temporal infinita. Ms usuales desde el punto de vista prctico son los pulsos de luz, que
tienen una extensin temporal finita. Las ondas que tienen una extensin espacial finita se tratan en temas de
difraccin.

Contenidos de este captulo:


Introduccin
Espectros de distintos tipos de pulso
Pulso gaussiano
Pulso exponencial: perfil de Lorentz
Pulso cuadrado
Suma de dos ondas

Herramientas utilizadas en este tutorial:


numpy: manipulacin bsica de arrays
scipy: tratamiento de datos matemticos
matplotlib.pyplot: visualizacin de datos similar a matplotlib
Descarga de archivos:
Generacin de espectros de un haz cuadrado pulso_cuadrado.py
Generacin de espectros tipo gaussiano pulso_gauss.py
Generacin de espectros tipo lorentziano pulso_lorentz.py

Superposicion de dos ondas en el vaco dos_ondas.py


Superposicion de dos ondas en un medio dispersivo dos_ondas_dispersivo.py
Superposicion de dos ondas en un medio dispersivo animacin dos_ondas_animacion.py
Superposicion de n ondas n_ondas.py
Superposicion de n ondas (animacin) n_ondas_animacion.py

Propagacin de un pulso en el vacio propagacion_pulso_vacio.py


Propagacin de un pulso en un medio dispersivo propagacion_pulso_dispersivo.py

129
PIMCD2013-python, Publicacin 1.0

Propagacin de un pulso (animacin) propagacion_pulso_dispesivo.py


Propagacin de un pulso, siguiendo la posicin del mximo (animacin)
propagacion_pulso_en_ola_animacion.py

10.1 Introduccin

Un pulso temporal plano se puede tratar como una suma infinita de ondas armnicas planas, pues forman una
base. Para calcular los componentes de cada una de las ondas armnicas de frecuencia que componen el pulso
se tiene que realizar una transformacin de Fourier temporal,

E (, ) = E0, ( ) ,

donde E0, es la amplitud compleja de cada una de las ondas planas. Para calcular esta amplitud se tiene que
recurir a la transformacin de Fourier inversa

1
E0, = E ( = 0, ) ,
2
Existen dos casos particularmente tiles como son el pulso gaussiano y el pulso de exponencial, que discutiremos
brevemente a continuacin.

10.2 Espectros de distintos tipos de pulso

10.2.1 Pulso gaussiano

El caso gaussiano tiene la forma

( 0 )2
[ ]
E0, = E0 .
2 2

donde 0 es la frecuencia central del pulso y 2 es la anchura espectral del pulso.


Si la onda se propaga por un medio no dispersivo de ndice de refraccin n, introduciendo 0, en (, ) se
obtiene que el campo resulta
( / )2 ( /)0
[ ]
E (, ) = 2E0 .
2/ 2

donde se observa que la amplitud y la fase se mueven con la misma velocidad.


En el siguiente cdigo se muestra cmo generar una grfica con el espectro gaussiano y el pulso generado.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""pulso de gauss"""

from __future__ import division


import locale

#Modulos empleados
import scipy as sp
import matplotlib.pyplot as plt

130 Captulo 10. Pulsos de luz


PIMCD2013-python, Publicacin 1.0

#Unidades
sg = 1
Hz = 1 / sg #hertzio

def pulso_gauss(w0=1, gamma=.1):


"""Entradas: w0: frecuencia de resonancia
gamma: amortiguamiento
"""
#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia
n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)

t= sp.linspace(-3/gamma,3/gamma,n_puntos)

#campo electrico normalizado


campo=sp.exp(-(gamma*t)**2/2)*sp.cos(w0*t)
#espectro normalizado
Espectro= sp.exp (-0.5*(w-w0)**2/(gamma)**2)

#Figura con campo y espectro


plt.figure(figsize=(10,5))

#Representacion del campo


plt.subplot(1,2,1)
plt.plot(t, campo, k, linewidth = 2)
plt.xlabel($t \; (s)$, fontsize = 18)
plt.ylabel($E(t)$, fontsize = 18)

#Representacion del espectro


plt.subplot(1,2,2)
plt.plot(w, Espectro, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel(perfil Gaussiano, fontsize = 18)
plt.tight_layout()

#Representacion de un pulso ejemplo con w0=3*10**15*Hz y gamma=10**14*Hz


pulso_gauss(w0=3*10**15*Hz, gamma=10**14*Hz)
plt.show()

1.0 1.0

0.8
0.5
perfil Gaussiano

0.6
E(t)

0.0
0.4

0.5
0.2

1.0 3 2 1 0 1 2 3 0.02.0 2.5 3.0 3.5 4.0


t (s) 1e 14 (Hz) 1e15

10.2. Espectros de distintos tipos de pulso 131


PIMCD2013-python, Publicacin 1.0

10.2.2 Pulso exponencial: perfil de Lorentz

Otro pulso que se utiliza frecuentemente es el pulso exponencial, pues es el modelo clsico de cmo los tomos
emiten luz. Una vez excitados pierden energa hasta que vuelven al estado estacionario. El modelo de Lorentz
asume que el desplazamiento resulta

r() = r /2 .

donde es la constante de decaimiento. Segn este modelo de Lorentz el campo generado

E( = 0, ) = 0 u /2 0 .

Al realizar la transformada de Fourier resulta que la distribucin de frecuencias es compleja (se producen desfases).
ux
E =
/2 ( )
En este caso, la densidad de energa espectral, esto es, la cantidad de energa electromagntica por unidad espectral
que llega por unidad de superficie

2 /4 1
() = | |2 = ( ) , = ( ) ,
2 /4 + ( )2 1 + 4( )2 / 2
En el siguiente cdigo se muestra cmo generar una grfica con el espectro gaussiano y el pulso generado.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""pulso de gauss"""

from __future__ import division


import locale
locale.setlocale(locale.LC_NUMERIC, C)
import scipy as sp
import matplotlib.pyplot as plt

#Definicion de frecuencia
sg= 1
Hz = 1 / sg #hertzio

def Lorentziana(w0=1, gamma=.1):


"""Entradas: w0: frecuencia de resonancia
gamma: amortiguamiento
"""
#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia
n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)
t= sp.linspace(0,100/w0,n_puntos)

#campo
campo=sp.exp(-gamma*t)*sp.cos(w0*t)

#Definicion del espectro espectro


Espectro= 1 / (1 + (w-w0)**2/(gamma/2)**2)

#Figuras
plt.figure(figsize=(10,5))

#Representacion del campo

132 Captulo 10. Pulsos de luz


PIMCD2013-python, Publicacin 1.0

plt.subplot(1,2,1)
plt.plot(t, campo, k, linewidth = 2)
plt.xlabel($t \; (s)$, fontsize = 18)
plt.ylabel($E(t)$, fontsize = 18)

#Representacion del espectro


plt.subplot(1,2,2)
plt.plot(w, Espectro, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel(perfil Lorenziano, fontsize = 18)
plt.tight_layout()

#Representacioni de un pulso lorentziano con w0=3*10**15*Hz, gamma=10**14*Hz


Lorentziana(w0=3*10**15*Hz, gamma=10**14*Hz)
plt.show()

1.0 1.0

0.8
0.5
perfil Lorenziano
0.6
E(t)

0.0
0.4

0.5
0.2

1.00.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 0.02.0 2.5 3.0 3.5 4.0
t (s) 1e 14 (Hz) 1e15

10.2.3 Pulso cuadrado

Desde el punto de vista terico tambin es importante un pulso cuadrado, que se obtiene como una funcin coseno
dentro del intervalo y 0 fuera.

r() = r /2 .

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""pulso de gauss"""

from __future__ import division


import locale

#Modulos empleados
import scipy as sp
import matplotlib.pyplot as plt

10.2. Espectros de distintos tipos de pulso 133


PIMCD2013-python, Publicacin 1.0

#Unidades
sg = 1
Hz = 1 / sg #hertzio

def pulso_gauss(w0=1, gamma=.1):


"""Entradas: w0: frecuencia de resonancia
gamma: amortiguamiento
"""
#frecuencia de la luz. Array con diversas frecuencias en torno a la resonancia
n_puntos = 1000
anchura = 10
w = sp.linspace(w0 - anchura * gamma, w0 + anchura * gamma, n_puntos)

t= sp.linspace(-3/gamma,3/gamma,n_puntos)

#campo electrico normalizado


campo=sp.exp(-(gamma*t)**200/2)*sp.cos(w0*t)
#espectro normalizado
Espectro= sp.sinc ((w-w0)/(gamma))

#Figura con campo y espectro


plt.figure(figsize=(10,5))

#Representacion del campo


plt.subplot(1,2,1)
plt.plot(t, campo, k, linewidth = 2)
plt.xlabel($t \; (s)$, fontsize = 18)
plt.ylabel($E(t)$, fontsize = 18)

#Representacion del espectro


plt.subplot(1,2,2)
plt.plot(w, Espectro, k, linewidth = 2)
plt.xlabel($\omega \; (Hz)$, fontsize = 18)
plt.ylabel(perfil sinc, fontsize = 18)
plt.tight_layout()

#Representacion de un pulso ejemplo con w0=3*10**15*Hz y gamma=10**14*Hz


pulso_gauss(w0=3*10**15*Hz, gamma=10**14*Hz)
plt.show()

1.0 1.0

0.8
0.5
0.6
perfil sinc

0.4
E(t)

0.0
0.2

0.0
0.5
0.2

1.0 3 2 1 0 1 2 3 0.42.0 2.5 3.0 3.5 4.0


t (s) 1e 14 (Hz) 1e15

134 Captulo 10. Pulsos de luz


PIMCD2013-python, Publicacin 1.0

10.3 Suma de dos ondas

Para analizar la propagacin de un pulso de luz, en primer lugar haremos la aproximacin de

10.3. Suma de dos ondas 135


PIMCD2013-python, Publicacin 1.0

136 Captulo 10. Pulsos de luz


CAPTULO 11

Interferencias

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto

Contenidos de este captulo:


Introduccin
Programacin
Interferencia entre dos ondas plana
Mtodo lineal
Mtodo funcional
Mtodo con clases
Interferencia entre dos haces de Gauss
Interferencia entre dos ondas esfricas
Interfermetro de Young
Interfermetro de Michelson
Desplazamiento combinado
Simulacin del interfermetro de Michelson

Herramientas utilizadas en este tutorial:


numpy: manipulacin de datos
scipy: Herramientas matemticas
Archivos necesarios para la clase interferencias:
camposXY.py. Archivo con las funciones principales de campos camposXY.py
fuentesXY.py. Archivo con las funciones principales de fuentes fuentesXY.py
Descarga de archivos:
Ejemplo de interferencias con ondas planas interferencias_ondasPlanas1.py
Ejemplo de interferencias con ondas planas interferencias_ondasPlanas2.py
Ejemplo de interferencias con ondas planas interferencias_ondasPlanas3.py
Ejemplo de interferencias con ondas esfricas interferencias_ondasEsfericas1.py
Ejemplo de interferencias con ondas esfricas interferencias_ondasEsfericas2.py
Ejemplo de interferencias con ondas esfricas interferencias_ondasEsfericas3.py
Ejemplo de interferencias con haces de Gauss interferencias_gauss1.py
Ejemplo de interferencias con haces de Gauss interferencias_gauss2.py
Ejemplo de interfermetro de Michelson interferencias_michelson.py

137
PIMCD2013-python, Publicacin 1.0

11.1 Introduccin

El efecto de las interferencias surge directamente de que las ecuaciones de Maxwell son lineales en los campos
elctricos y magnticos. Supongamos que E1 y E2 son soluciones. Entonces

E = E1 + E2

tambin es una solucin. Sin embargo, el campo no es un parmetro observable, sino que lo es el promedio
temporal del vector de Poynting, que se define como
1
S E B,
0

con tiene unidades de [S] = /2 . Al particularizar al caso de ondas armnicas planas tenemos

1 0 2
S = |E| u ,
2 0

que es cuadrtico con el campo elctrico.


Si definimos la intensidad como

2
= |E| ,

entonces la intensidad de la composicin de las dos ondas resulta



2 2 2
= |E1 + E2 | = |E1 | + |E2 | + 2 |E1 E*2 | = 1 + 2 + 2 |E1 E*2 | .

Si no existiera el tercer trmino, entonces ocurre que = 1 + 2 , que es lo que normalmente vemos en la
naturaleza.
Para que se cumplan las interferencias, pues necesitamos que la luz est polarizada, sea bastante monocromtica
y sea coherente. En particular, se deben verificar:
nicamente interfieren ondas con la misma frecuencia, 1 = 2
Las ondas que interfieren deben tener estados de polarizacin no ortogonales. E01 E02 = 0
Coherencia: Las fases en el trmino interferencial deben tener poca dependencia de (, )
En este captulo asumiremos las mejores condiciones para producir las interferencias. Las 2 ondas tienen la misma
polarizacin, son puramente monocromticas y coherentes. De esta forma, desaparece el carcter vectorial de las
interferencias.

11.2 Programacin

Debido a la sencillez conceptual de las interferencias, las utilizaremos para analizar los distintos tipos de pro-
gramacin que se puede realizar con Python, como es la programacin con scripts (todo el cdigo en un mismo
archivo lineal), la programacin funcional (se escriben funciones que simplifican lo clculos) y la programacin
con clases (donde funciones y datos estn ntimamente relacionados). Finalmente veremos un procedimiento sen-
cillo para desarrollar vdeos, simulando un interfermetro de Michelson.

11.3 Interferencia entre dos ondas plana

En representacin compleja una onda plana se expresa como

(r, ) = (k r)

138 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

Podemos desciribr el vector k en coordenadas esfericas, de forma que tenemos


2
k= (sin sin , cos sin , cos ).

2
Entonces, en el plano = 0, la componente k r = ( + ).
Esto se puede programar en Python como
k*(X*sp.sin(theta1)*sp.sin(phi1)+Y*sp.cos(theta1)*sp.sin(phi1))

para poder representar esta ecuacin en muchas posiciones x,y entonces X e Y son matrices generadas como
tamano=100*um
x=sp.linspace(-tamano,tamano, 256)
y=sp.linspace(-tamano,tamano, 256)
X,Y=sp.meshgrid(x,y)

11.3.1 Mtodo lineal

El mtodo lineal es quizs el ms sencillo para iniciarse, pues la programacin est en el mismo archivo y el
cdigo se ejecuta de arriba hacia abajo en el programa. Un ejemplo de esta programacin est en la funcin
interferencias_ondasPlanas1.py. El archivo consiste en la definicin de dos ondas de la misma longitud de onda y
la posterior superposicin de las mismas, para finalmente obtener la intensidad. As se obtiene el patrn de franjas
de la figura.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
Interferencia entre ondas planas.
Programacion lineal.
"""

#Carga de paquetes y librerias


import scipy as sp
import matplotlib.pyplot as plt

#variables globales
um=1
grados=sp.pi/180

#Longitud de onda y vector de onda


wavelength=0.6328*um
k=2*sp.pi/wavelength

#Tamano
tamano=100*um
x=sp.linspace(-tamano,tamano, 256)
y=sp.linspace(-tamano,tamano, 256)
X,Y=sp.meshgrid(x,y)

#amplitud y direccion de la primera onda


A1=1
theta1=90*grados
phi1=-1*grados

#direccion de la segunda onda (distinta direccion)

11.3. Interferencia entre dos ondas plana 139


PIMCD2013-python, Publicacin 1.0

A2=1
theta2=90*grados
phi2=1*grados

#definicion de una onda plana (observese la generacion de numeros complejos)


u1=A1*sp.exp(1.j*k*(X*sp.sin(theta1)*sp.sin(phi1)+Y*sp.cos(theta1)*sp.sin(phi1)))
u2=A2*sp.exp(1.j*k*(X*sp.sin(theta2)*sp.sin(phi2)+Y*sp.cos(theta2)*sp.sin(phi2)))

#proceso interferencial
u=u1+u2

#calculo de la intensidad
I=abs(u)**2

#grafica de la intensidad
plt.figure() #creacion de la figura

#datos para ajustar el dibujo a la escala


extension = [x.min(), x.max(), y.min(), y.max()]

#dibujar intensidad + acondicionamiento de la grafica


h1 = plt.imshow(I, interpolation = bilinear, aspect = auto,
origin = lower, extent = extension)

#escalado de la grafica
plt.axis(scaled)

#etiquetas
plt.xlabel("$x (\mu m)$", fontsize = 22)
plt.ylabel("$y (\mu m)$", fontsize = 22)
plt.title("$Intensidad(x,y)$", fontsize = 22)

#color
h1.set_cmap("gist_heat")

#dibujar barra de colores


plt.colorbar()

#muestra la grafica
plt.show()

140 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

100
Intensidad(x,y) 4.0
3.6
3.2
50
2.8
2.4
y(m)

0 2.0
1.6
1.2
50
0.8
0.4
100100 50 0 50 100 0.0
x(m)
11.3.2 Mtodo funcional

Si nos damos cuenta en el cdigo anterior, la onda plana se generar dos veces, una para 1 , y otra para 2 . Esto
se puede evitar definiendo una funcin que denominamos onda_plana() a la cual llamamos dos veces. Los
parmetros de entrada de la funcin son aquellos que alguna vez podemos variar. Tambin podemos generar una
funcin que realiza la grfica. De esta forma la podemos llamar tambin varias veces.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
Interferencia entre ondas planas.
Programacion con funciones.
"""

#Carga de librerias y paquetes.


import scipy as sp
import matplotlib.pyplot as plt

#variables globales
um=1
grados=sp.pi/180

#parametros opticos
wavelength=0.6328*um

11.3. Interferencia entre dos ondas plana 141


PIMCD2013-python, Publicacin 1.0

k=2*sp.pi/wavelength

#Tamano
tamano=100*um
x=sp.linspace(-tamano,tamano, 256)
y=sp.linspace(-tamano,tamano, 256)
X,Y=sp.meshgrid(x,y)

def onda_plana(A, theta, phi):


#definicion de una onda plana (observese la generacion de numeros complejos)
u=A*sp.exp(1.j*k*(X*sp.sin(theta)*sp.sin(phi)+Y*sp.cos(theta)*sp.sin(phi)))
return u

#definicion de la grafica
def dibujar_grafica(I):
#grafica de la intensidad
plt.figure() #creacion de la figura
#datos para ajustar el dibujo a la escala
extension = [x.min(), x.max(), y.min(), y.max()]
#dibujar intensidad + acondicionamiento de la grafica
h1 = plt.imshow(I, interpolation = bilinear, aspect = auto,
origin = lower, extent = extension)
#escalado de la grafica
plt.axis(scaled)
#etiquetas
plt.xlabel("$x (\mu m)$", fontsize = 22)
plt.ylabel("$y (\mu m)$", fontsize = 22)
plt.title("$Intensidad(x,y)$", fontsize = 22)
#color
h1.set_cmap("gist_heat") #RdBu
#dibujar barra de colores
plt.colorbar()

#generacion de las ondas planas,


#ahora no es necesario definir los parametros globalmente, sino como parametros de la funcion
u1=onda_plana(A=1,theta=90*grados,phi=-1*grados)
u2=onda_plana(A=1,theta=90*grados,phi=1*grados)
#proceso interferencial
u=u1+u2
#calculo de la intensidad
I=abs(u)**2
dibujar_grafica(I)

#El codigo se puede reutilizar para otro ejemplo


u3=onda_plana(A=1,theta=90*grados,phi=0*grados)
u4=onda_plana(A=1,theta=90*grados,phi=4*grados)
#proceso interferencial
u=u3+u4
#calculo de la intensidad
I=abs(u)**2
dibujar_grafica(I)
plt.show()

142 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

100
Intensidad(x,y) 4.0
3.6
3.2
50
2.8
2.4
y(m)

0 2.0
1.6
1.2
50
0.8
0.4
100100 50 0 50 100 0.0
x(m)
100
Intensidad(x,y) 4.0
3.6
3.2
50
2.8
2.4
y(m)

0 2.0
1.6
1.2
50
0.8
0.4
100100 50 0 50 100 0.0
x(m)
Como se ve, el cdigo incluido en las funciones se puede reutilizar. No obstante, las variables que utiliza la funcion

11.3. Interferencia entre dos ondas plana 143


PIMCD2013-python, Publicacin 1.0

onda_plana() tienen dos orgenes. Uno como variables globales definidas anteriormente (como puede ser k,
X, Y y otras variables que se introducen a travs de la defincin de la funcin A, , .

11.3.3 Mtodo con clases

En las clases, las funciones y los datos estn todos bajo un mismo marco, por lo que no existe el peligro de
modificar las variables globales de forma inadvertida. Normalmente la clase se define en una funcin (compleja)
y las aplicaciones de la clase llaman a esta funcin. Esta forma permite generar las figuras mostradas debajo del
cdigo
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
Metodo que utiliza las clases
"""

#Carga de paquetes y librerias


import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)
from fuentesXY import fuenteXY, grados

#genera una instancia a una fuente


#estamos utilizando los parametros predeterminados para las variables de inicializacion
# (x, y, wavelength)

u1 = fuenteXY()
u2 = fuenteXY()

#rellena la instancia con una onda plana


u1.onda_plana(A = 1, theta = sp.pi / 2, phi = .5 * grados)
u2.onda_plana(A = 1, theta = sp.pi / 2, phi = -.5 * grados)

#segun la definicion de la clase la suma de dos ondas tambien es una onda


u12 = u1 + u2

#llama a la funcion de dibujar,


#esta funcion tiene varios metodos y elegimos dibujar la intensidad
u12.dibujar(tipo=intensidad)

#ahora elegimos dibujar el campo


u12.dibujar(tipo=campo)

plt.show()

144 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

4.0
200 3.6
3.2
100 2.8
2.4
y(m)

0 2.0
1.6
100 1.2
0.8
200 0.4

200 100 0 100 200 0.0


x(m)
amplitud fase
200 200

100 100
y(m)

y(m)

0 0

100 100

200 200
200 100 0 100 200 200 100 0 100 200
x(m) x(m)
0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 0.0 0.4 0.8 1.2 1.6 2.0 2.4 2.8

Dentro de la clase fuentesXY (no es necesario comprender todas las funciones todava), las funciones que
hemos utilizado son:
__init__()
onda_plana()
def __init__(self, x = x0, y = y0, wavelength = lambda0):
"""Se inicia un nuevo experimento"""
#arrays de entrada

11.3. Interferencia entre dos ondas plana 145


PIMCD2013-python, Publicacin 1.0

self.x = x
self.y = y
#Longitud de onda
self.wavelength = wavelength
#Generacion de un mallado
self.X, self.Y = sp.meshgrid(x, y)
#Predefinicion del campo
self.u = sp.zeros(sp.shape(self.X), dtype = complex)

def onda_plana(self, A = 1, theta = 0 * grados, phi = 0 * grados):


"""onda plana"""
#Definicion del vector de onda
k = 2 * sp.pi / self.wavelength

#Definicion de la onda plana (coordenadas esfericas)


self.u = A * sp.exp(1.j * k * (self.X * sp.sin(theta) * sp.sin(phi) \
+ self.Y * sp.cos(theta) * sp.sin(phi)))

11.4 Interferencia entre dos haces de Gauss

Veamos ahora el proceso de interferencia de 2 haces de Gauss. Estos hace se pueden definir como

2 2
( ) ( )
0
(, , ) = 0 exp 2 exp + ()
() () 2()
donde
0
02 =

( )2

() = 0 1+
0

[ ]
2
() = 1 + ( )
0
Este tipo de haces se puede programar fcilmente. Asumamos que estamos en el foco del haz z=0 y los haces estn
rotados. Entonces tambin se van a producir interferencias entre los haces.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
ejemplos de interferencias
"""

#Carga de paquetes y librerias


import scipy as sp
import matplotlib.pyplot as plt

#variables globales
um=1
grados=sp.pi/180

#Longitud de onda y mallado

146 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

wavelength=0.6328*um
tamano=100*um
x=sp.linspace(-tamano,tamano, 256)
y=sp.linspace(-tamano,tamano, 256)
X,Y=sp.meshgrid(x,y)

def gauss(A=1, r0=(0*um,0*um), w=100*um, theta=0.*grados, phi=0*grados):


"""haz gaussiano."""
x0,y0=r0
#vector de onda
k=2*sp.pi/wavelength
#Amplitud de la onda
amplitud=A*sp.exp(-(X-x0)**2/(2*w**2)-(Y-y0)**2/(2*w**2))
#Fase de la onda
fase=sp.exp(1.j*k*(X*sp.sin(theta)*sp.sin(phi)+Y*sp.cos(theta)*sp.sin(phi))) #rotacion
#Campo
u=amplitud*fase
return u

def dibujar(Intensidad, titulo):


"""Dibuja el patron de intensidad"""
#Creamos una figura
plt.figure()
h1 = plt.imshow(Intensidad)
#Mapa de color
h1.set_cmap("gist_heat") #RdBu
#Titulo y escala de color
plt.title(titulo, fontsize=28)
plt.colorbar()

def interferenciasGauss(theta, titulo=):


#Campos de las ondas que interfieren
u1=gauss(A=1, r0=(0*um,0*um), w=50*um, theta=theta, phi=2*grados)
u2=gauss(A=1, r0=(0*um,0*um), w=50*um, theta=-theta, phi=2*grados)
#Superposicion
u=u1+u2
#Intensidad de la superposicion
Intensidad=abs(u)**2
#Representacion
dibujar(Intensidad, titulo)

if __name__ == __main__:
interferenciasGauss(theta=20*grados, titulo=r$\theta=20^{0}$)
interferenciasGauss(theta=40*grados, titulo=r$\theta=40^{0}$)
plt.show()

11.4. Interferencia entre dos haces de Gauss 147


PIMCD2013-python, Publicacin 1.0

0
=200
3.6
50 3.2
2.8
100 2.4
2.0
150 1.6
1.2
200 0.8
0.4
250 0.0
0 50 100 150 200 250

0
=400
3.6
50 3.2
2.8
100 2.4
2.0
150 1.6
1.2
200 0.8
0.4
250 0.0
0 50 100 150 200 250

Aqu est todo programado en funciones, tanto la amplitud del haz de Gauss en z=0, como el procedimiento de

148 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

dibujar y la funcin de ejecucin __main__. De esta forma se puede reutilizar el cdigo de una forma muy
eficiente, adems de entenderse mejor el cdigo. Los parmetros entre las funciones se pasan a travs de las
variables de entrada.
Finalmente, vemos cmo se puede representar esto a partir de la clase FuenteXY. La forma de programar las
interferencias es mucho ms sencilla y clara, casi pseudocdigo
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
ejemplos de interferencias
"""
#Carga de paquetes y librerias
import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)
from fuentesXY import fuenteXY, grados, um

#definicion de parametros
x=sp.linspace(-100*um,100*um,256)
y=sp.linspace(-100*um,100*um,256)
wavelength=0.6328*um
#onda 1
u1 = fuenteXY(x,y,wavelength)
u1.haz_gauss(A=1, r0=(0*um,0*um), w=(50*um, 50*um), theta=20.*grados, phi=2*grados)
#onda 2
u2 = fuenteXY(x,y,wavelength)
u2.haz_gauss(A=1, r0=(0*um,0*um), w=(50*um, 50*um), theta=-20.*grados, phi=2*grados)
#Superposicion
u12 = u1 + u2
#Representacion
u12.dibujar(tipo=intensidad)
plt.show()

11.4. Interferencia entre dos haces de Gauss 149


PIMCD2013-python, Publicacin 1.0

100
3.6
3.2
50
2.8
2.4
y(m)

0 2.0
1.6
1.2
50
0.8
0.4
100100 50 0 50 100 0.0
x(m)

11.5 Interferencia entre dos ondas esfricas

Como ejemplo de programacin con clases veremos las interferencias entre ondas esfricas. Estas son de gran
importancia terica pues nos permiten analizar los interfermetros de Young y de Michelson. La diferencia fun-
damental estriba en la posicin de las fuentes. Mientras que en el interfermetro de Young las dos fuentes estn
desplazadas en el eje x, en el interferometro de Michelson estn desplzadas en el eje z.
Como veremos, la programacin con clases nos permite centrarnos en el problema, ya que la programacin es de
alto nivel (el profesor ya desarrolla las funciones de generacin de las fuentes).

11.5.1 Interfermetro de Young

Como hemos dicho las dos fuentes estn desplazadas en el eje x. Esto genera una distribucin de intensidad en
forma de elipses que, si nos centramos en el eje, son muy prximas a franjas verticales, como puede ver en la
siguiente funcin.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Interferencias entre 2 ondas esfericas desplazadas en el eje x
#-------------------------------------

#Carga de librerias y paquetas


import scipy as sp
import matplotlib.pyplot as plt

150 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

import sys
sys.path.append(../)
from fuentesXY import fuenteXY, grados, um

#definicion de las ondas


u1 = fuenteXY();
u1.onda_esferica(A = 1, r0 = (-10 * um, 0 * um), z0 = -1000 * um, radio = 200 * um, mascara = True
u2 = fuenteXY()
u2.onda_esferica(A = 1, r0 = (+10 * um, 0 * um), z0 = -1000 * um, radio = 200 * um, mascara = True

#definicion de las interferencias


u12 = u1 + u2
u12.dibujar(tipo=intensidad)

plt.show()

200 3.6
3.2
100 2.8
2.4
y(m)

0 2.0
1.6
100 1.2
0.8
200 0.4

200 100 0 100 200 0.0


x(m)
11.5.2 Interfermetro de Michelson

Ahora las fuentes estn desplazadas en el eje z. Esto genera una distribucin de intensidad en forma de anillos,
como se puede ver en la siguiente funcin.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""

11.5. Interferencia entre dos ondas esfricas 151


PIMCD2013-python, Publicacin 1.0

Interferencias
"""
#Carga de paquetes y librerias
import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)
from fuentesXY import fuenteXY, grados, um

#Definicion de las ondas


u1 = fuenteXY()
u1.onda_esferica(A = 1, r0 = (0 * um, 0 * um), z0 = -1000 * um, radio = 200 * um, mascara = True)
u2 = fuenteXY()
u2.onda_esferica(A = 1, r0 = (0 * um, 0 * um), z0 = -1500 * um, radio = 200 * um, mascara = True)

#Superposicion y dibujo de la intensidad


u12 = u1 + u2
u12.dibujar()

plt.show()

0.0000027
200
0.0000024
0.0000021
100
0.0000018
0.0000015
y(m)

0
0.0000012

100 0.0000009
0.0000006

200 0.0000003

200 100 0 100 200 0.0000000


x(m)
11.5.3 Desplazamiento combinado

Cuando tenemos un desplazamiento combinado x-z entre las dos fuentes, entonces la situacin no es tan sencilla,
apareciendo unas elipses que nos son familiares si hemos ajustado un interfermetro de Michelson.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------

152 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

# Autor: Luis Miguel Sanchez Brea


# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
Interferencias
"""

#Carga de paquetes y librerias


import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)
from fuentesXY import fuenteXY, grados, um

#Definicion de las ondas


u1 = fuenteXY()
u1.onda_esferica(A = 1, r0 = (-20 * um, 0 * um), z0 = -1000 * um, radio = 100 * um, mascara = Fals
u2 = fuenteXY()
u2.onda_esferica(A = 1, r0 = (+20 * um, 0 * um), z0 = -1100 * um, radio = 100 * um, mascara = Fals

#Superposicion de las ondas


u12 = u1 + u2

#Representacion
u12.dibujar(tipo=intensidad)
plt.show()

0.0000036
200 0.0000032
0.0000028
100
0.0000024
0.0000020
y(m)

0
0.0000016
0.0000012
100
0.0000008

200 0.0000004

200 100 0 100 200


x(m)

11.5. Interferencia entre dos ondas esfricas 153


PIMCD2013-python, Publicacin 1.0

11.5.4 Simulacin del interfermetro de Michelson

Para finalizar mostramos un cdigo que ejecuta un vdeo de qu ocurre en un interfermetro de Michelson cuando
uno de los espejos se desplaza.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: grafica animada simulando un interferometro de Michelson
#-------------------------------------

import time
import gobject
import gtk #@UnusedImport

import scipy as sp

import matplotlib
matplotlib.use(GTKAgg)
import matplotlib.pyplot as plt
import matplotlib.cm as cm

um=1;
mm=1000*um;

fig = plt.figure(1)
a = plt.subplot(111)

wavelength=0.6328*um
k=2*sp.pi/wavelength

d=.25*mm #separacion entre espejos


x=sp.linspace(-15*mm,15*mm,256)
y=sp.linspace(-15*mm,15*mm,256)
z=250*mm #camino recorrido por la luz

X,Y=sp.meshgrid(x,y)

#acelera los calculos


cos_theta=z/sp.sqrt(X**2+Y**2+z**2)

I=1+sp.cos(2*k*d*cos_theta)

im = a.imshow( I, cmap=cm.gist_heat)

manager = plt.get_current_fig_manager()
cnt = 0
tstart = time.time()

def updatefig(*args):
#parametros globales definidos fuera de la funcion
global x, y, cnt, start, k, cos_theta, d
d-=.025*um
I=1+sp.cos(2*k*d*cos_theta)
im.set_array(I)
manager.canvas.draw()
cnt += 1
if cnt==250:
FPS=cnt/(time.time() - tstart)

154 Captulo 11. Interferencias


PIMCD2013-python, Publicacin 1.0

print "FPS: %4.2f" %FPS


return False
return True

cnt = 0

gobject.idle_add(updatefig)
plt.show()
tmp=raw_input("pulse enter para cerrar:")

11.5. Interferencia entre dos ondas esfricas 155


PIMCD2013-python, Publicacin 1.0

156 Captulo 11. Interferencias


CAPTULO 12

Mdulos de ptica

Una vez que conocemos los mdulos cientficos, en el Departamento de ptica de la UCM hemos desarrollado
mdulos especficos para aplicaciones pticas. .

12.1 Clase camposXY

Autor Luis Miguel Snchez Brea

Contenidos de este captulo:


Introduccin
Inicializacin de la clase
Funciones que operan sobre los campos
Funciones que discretizan los campos
Funciones que propagan los campos
Funciones que dibujan los campos

Herramientas utilizadas en este tutorial:


Archivo con las funciones principales camposXY.py
Archivos necesarios para el anlisis de camposXY:
Archivo con funciones de verificacin de las grficas camposXY_testsDibujar.py
Archivo con funciones de verificacin de las operaciones con los campos
camposXY_testsOperaciones.py
Archivo con funciones de verificacin de herramientas pticas camposXY_testsOptica.py

12.1.1 Introduccin

La mayor parte de las veces observamos un campo ptico en un plano XY, como es en el caso de la deteccin
sobre una pantalla o sobre una cmara CCD o CMOS.
Aqu es donde vamos a definir los campos elctricos de observacin. En este mdulo realizaremos un tratamiento
escalar, que permitir realizar operaciones sobre el campo elctrico. Asimismo, ser utilizado por otros mdulos
como mascarasXY.py y fuentesXY.py, puesto que las mscaras y las fuentes se pueden tratar de idntica forma.
En este captulo se pretende estudiar el funcionamiento del mdulo, no desarrollar ejemplos y aplicaciones pticas.

12.1.2 Inicializacin de la clase

Se inicializa con la funcin __init__ que dice las operaciones cuando se carga.

157
PIMCD2013-python, Publicacin 1.0

def __init__(self, x = x0, y = y0, wavelength = lambda0):

Esta funcin inicia la clase y genera los arrays de datos necesarios


x, y - arrays unidimensionales de tamao numx y numy, con las posiciones de los pixeles de la mscara
X, Y - arrays bidimensionales de tamao (numx,numy) con las posiciones de los pixeles de la mscara
wavelength - longitud de onda incidente (monocromtico)
u - campo o transmitancia generada por la fuente / mscara. Matriz bidimensional con el tamao
(numx,numy).
Ejemplo de uso:
tamano = 250 * um
x0 = sp.linspace(-tamano * um, tamano * um, 256)
y0 = sp.linspace(-tamano * um, tamano * um, 256)
wavelength = 0.6328 * um

campo = campoXY(x = x0, y = y0, wavelength = wavelength)

El campo self.u es nulo hasta que no se utilice una funcin que lo rellena.

12.1.3 Funciones que operan sobre los campos

Archivo con funciones de verificacin de las operaciones con los campos


camposXY_testsOperaciones.py
Se ejecutan las siguientes funciones:
def testCamposXY():
"""poner un comentario # en aquellas funciones que no se quieren ejecutar"""
#test_getAmplitud()
#test_getFase()
#test_quitarAmplitud()
#test_quitarFase()
#test_binarizarAmplitud()
#test_binarizarFase()
#test_campoXY_is()
test_campoXY_recortar()
#test_campoXY_extender()
#test_campoXY_redimensionar()
#test_campoXY_normalizar()
#test_cargarGuardatDatoscPickle()

Veamos algunas de las funciones que se utilizan:


def __add__(self, other):
def __mul__(self, other):

Devuelven un campo nuevo que es la suma o multiplicacin:


u3.u = self.u + other.u
u3.u = self.u * other.u

Los dos campos que se suman o multiplican tienen que tener la misma dimensin. Un pequeo ejemplo de uso.
Utilizamos la clase fuenteXY, pero es lo mismo, pues una hereda las funciones de la otra.
u1 = fuenteXY()
u2 = fuenteXY()

#rellena la instancia con una onda plana


u1.onda_plana(A = 1, theta = sp.pi / 2, phi = .5 * grados)
u2.onda_plana(A = 1, theta = sp.pi / 2, phi = -.5 * grados)

158 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

#segun la definicion de la clase la suma de dos ondas tambien es una onda


u12 = u1 + u2

Devuelven True o False si son solo de amplitud o de fase.


def isFase(self, nivelContraste = 0.01):
def isAmplitud(self, nivelContraste = 0.01):

Devuelven True o False si son solo de amplitud o de fase.


def recortar(self, xmin = 0, xmax = 1, ymin = 0, ymax = 1, campoNuevo = True):
def extender(self, xmin = 0, xmax = 1, ymin = 0, ymax = 1, ufondo = 0, campoNuevo = True):
def redimensionar(self, npuntos = 512, campoNuevo = True):

Otro tipo de operaciones que extrae informacin de los campos:


def getAmplitud(self, matriz = False, newField = False):
def getFase(self, matriz = False, newField = False):
def quitarAmplitud(self, matriz = False, newField = False):
def quitarFase(self, signo = False, matriz = False, newField = False):
def amplitud2fase(self, matriz = False, newField = False):
def fase2amplitud(self, matriz = False, newField = False):
def normalizar(self, tipo = intensidad):

def binarizar(self, tipo = "amplitud", corte = None, nivel0 = None, nivel1 = None, campoNuevo = Fa
def perfil(self, punto1=, punto2=, npixels=1000, tipo=intensidad, order=2):

12.1.4 Funciones que discretizan los campos

Archivo con funciones de verificacin de herramientas pticas camposXY_testsDiscretizar.py


Se ejecutan las siguientes funciones:
def testCamposXY():
"""poner un comentario # en aquellas funciones que no se quieren ejecutar"""
test_discretizar_1()
test_discretizar_2()
test_discretizar_3()
test_discretizar_4()

def discretizar(self, tipo = amplitud, numNiveles = 2, factor = 1, desfaseInicial = 0, campoNuev

12.1.5 Funciones que propagan los campos

Archivo con funciones de verificacin de herramientas pticas camposXY_testsOptica.py


Las funciones del modulo son las siguientes:
Transformada de Fourier
def fft(self, focal = 10 * mm, shift = True, quitar0 = True, matriz = False):
def ifft(self, focal = 10 * mm, shift = True, quitar0 = True, matriz = False):

Rayleigh-Sommerfeld:
def RS(self, z = 10 * mm, newField = True, xout = None, yout = None):
def progresion(self, zs=sp.linspace(1*mm,2*mm,500), tipo=intensidad, generarTemporales=True):

Los tests de verificacin de estas funciones son las siguientes:

12.1. Clase camposXY 159


PIMCD2013-python, Publicacin 1.0

def testCamposXY():
"""poner un comentario # en aquellas funciones que no se quieren ejecutar"""
#test_FFT_ondaPlana()
#test_FFT_Gauss()
#test_FFTrectangulo()
#test_RS()
test_RS_tamano_distinto()
#test_RS_inversa()
#test_variosPasos()

12.1.6 Funciones que dibujan los campos

Archivo con funciones de verificacin de las grficas camposXY_testsDibujar.py


Se ejecutan las siguientes funciones:
def testCamposXY():
test_dibujar_campo()
test_dibujar_perfil()
test_dibujar_perfil_manual()
test_dibujar_varios_campos()

Las ejemplos se basan en la funcin self.dibujar() que dibuja los datos que hay en los campos. Hay diversos tipos
de dibujos intensidad, amplitud, fase, campo, campoReal.
def dibujar(self, tipo = intensidad, logaritmico = False, normalizar = False,\
titulo = " ", nombreArchivo = , dibujar = True, valorCorte = 1):
""" * tipo: intensidad, amplitud, fase, campo, campoReal
* logartimico: True o False
* normalizar: maximo, area, intensidad """

Asimismo es muy sencillo realizar dibujos logaritmicos, simplemente incluyendo True o False en la variable.
Si la variable nombreArchivo no es nula, se guarda un dibujo.
Si la variable normalizar es True el valor mximo del dibujo es la unidad.
Si se incluye un valorCorte, entonces se satura el dibujo al valor determinado.
Otra funcin que tambin es interesante es la de dibujar_perfil, que permite sacar una grfica 1D del camp entre 2
puntos.
def dibujar_perfil(self, punto1=, punto2=, npixels=1000, tipo=intensidad, normalizar=, ord

12.2 Clase fuentesXY

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto

Contenidos de este captulo:


Introduccin
Cmo funciona la clase fuentesXY
Onda plana
Onda esfrica
Haz de Gauss
Vrtice
Haz de Laguerre
Aberraciones: Haces de Zernike

160 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

Archivos necesarios en esta seccin:


fuentesXY.py. Archivo con las funciones principales fuentesXY.py
camposXY.py. clase con distintas funciones tales como inicializacin de parmetros o discretizacin entre
otros camposXY.py
test_onda_plana.py. Archivo con las funciones principales test_onda_plana.py
test_onda_esferica.py. Archivo con las funciones principales test_onda_esferica.py
test_laguerre.py. Archivo con las funciones principales test_laguerre.py
test_1laguerre.py. Archivo con las funciones principales test_1laguerre.py
test_vortices.py. Archivo con las funciones principales test_vortices.py
test_zernikes.py. Archivo con las funciones principales test_zernikes.py
Contenidos de los archivos:
fuentesXY.py:
onda_plana(). Simula una onda plana.
onda_esferica(). Simula una onda plana.
haz_gauss(). Genera un haz gaussiano.
haz_vortice(). Genera un haz con estructura tipo vrtice.
haz_laguerre(). Simula un haz de Laguerre.
fZernike(). Simula haces con aberraciones de Zernike.

12.2.1 Introduccin

Para poder realizar tratamientos numricos con haces de luz, lo primero que tenemos que hacer es definirlos. La
clase fuentesXY hereda las propiedades de la clase campoXY. Aade fuentes que se observan en el plano XY.
Para ello hemos desarrollado una clase que contiene distintos tipos de fuentes tales como ondas planas, ondas
esfricas, haces de Gauss, haces de Laguerre, vrtices y Zernikes. Veremos aqu las definiciones y los ejemplos
de utilizacin.

12.2.2 Cmo funciona la clase fuentesXY

La clase fuentesXY est constituida por un conjunto de funciones. Estas funciones describen distintos tipos de
onda o fuentes de luz en forma de: onda plana, esfrica, haz gaussiano, haz de Laguerre, o aberraciones de Zernike.
En el archivo fuentesXY_ejemplos, se muestra la obtencin de las figuras de cada apartado.
La clase FuentesXY hereda funciones de la clase camposXY, que ms general. No es necesario conocer el funcio-
namiento de esta clase camposXY. Cuando haga falta se har referencia a ella como, por ejemplo, al realizar las
grficas.
A modo de ejemplo veamos como se define y utiliza una fuente:
#definicion de parametros iniciales
tamano = 250 * um
npixels = 256
x0=sp.linspace(-tamano / 2, tamano / 2, npixels)
y0=sp.linspace(-tamano / 2, tamano / 2, npixels)
#Generacion de la clase
campo = fuenteXY(x = x0 , y = y0 , wavelength = 0.6328 * um)
#carga de la onda plana
campo.onda_plana(phi = 2 * grados, theta = 5 * grados)
#dibujar y guardar (si se escribe nombreArchivo)
campo.dibujar(tipo = fase)

12.2. Clase fuentesXY 161


PIMCD2013-python, Publicacin 1.0

12.2.3 Onda plana

Se define una onda plana como aquella que su frente de onda es plano y normal a la velocidad de fase. Son
uno de los tipos de ondas ms habituales en fsica. Y estn definidas en regiones suficientemente alejadas de
fuentes de carga. Su representacin matemtica se realiza mediante funciones armnicas, as sea una onda plana
propagndose en el eje z con amplitud A, frecuencia constante, , y con vector de onda = 2 (sin() sin
+
cos() sin ), la orientacin de los frentes de onda queda definida por dicho vector. De este modo, una onda
plana se expresa como

= .

En rigor, estamos obviando la parte temporal, puesto que a nuestros fines carece de importancia.
En representacin compleja una onda plana se expresa como

(r, ) = (k r)

Podemos describir el vector k en coordenadas esfricas, de forma que tenemos


2
k= (sin , cos sin , cos )

2
Entonces, en el plano = 0, la componente k r = ( + ).
Esto se puede programar en Python como
k*(X*sp.sin(theta1)*sp.sin(phi1)+Y*sp.cos(theta1)*sp.sin(phi1))

para poder representar esta ecuacin en muchas posiciones x,y entonces X e Y son matrices generadas como
tamano=100*um
x=sp.linspace(-tamano,tamano, 256)
y=sp.linspace(-tamano,tamano, 256)
X,Y=sp.meshgrid(x,y)

La definicin de la onda plana es sencilla:


Se puede realizar una representacin en el plano XY de los frentes de onda como se muestra en la figura. La
inclinacin de las franjas obedece a la direccin del vector de onda. Finalmente, puede apreciarse como los frentes
de onda son normales a dicho vector.
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#----------------------------------------------------------------------
# Name: fuentesXY.py
#Author: Luis Miguel Sanchez Brea
# Licence: GPL
#----------------------------------------------------------------------
"""
Clases campoXY y Fuentes2D con las fuentes utilizadas para propagacion
"""

from __future__ import division

import scipy as sp
import matplotlib.pyplot as plt
import sys
sys.path.append(../)

from camposXY import campoXY, um, mm, grados


from fuentesXY import fuenteXY

def test_onda_plana():
"""Generacion de una onda plana"""

162 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

#definicion de parametros iniciales


tamano = 250 * um
npixels = 256
#Generacion de la clase
x0=sp.linspace(-tamano / 2, tamano / 2, npixels)
y0=sp.linspace(-tamano / 2, tamano / 2, npixels)

campo = fuenteXY(x = x0 , y = y0 , wavelength = 0.6328 * um)


#carga de la onda plana
campo.onda_plana(phi = 2 * grados, theta = 5 * grados)
#dibujar y guardar
campo.dibujar(tipo = fase)

test_onda_plana()
plt.show()

100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)
12.2.4 Onda esfrica

De manera anloga a la definicin de onda plana, una onda esfrica es aquella cuyos frentes de onda son superficies
esfricas. Las ecuaciones de Maxwell postulan la existencia de ondas electromagnticas mediante la ecuacin de
ondas. La resolucin en esfricas de esta ecuacin da lugar a ondas esfricas como soluciones a las ecuaciones de
Maxwell. As se puede probar como la magnitud del campo elctrico viene definida mediante

= .

Las ondas esfricas han sido implementadas dentro de la clase fuenteXY mediante la funcin onda_esferica,
como se muestra en el cdigo a debajo. La onda encuentra su fuente de emisin centrada en el punto de coorde-
nadas x0, y0. Debido a que los frentes de onda son crculos concntricos, se ha definido una mscara circular
con el fin de no cortar ningn frente de onda, representando as nicamente los frentes de onda en el interior de

12.2. Clase fuentesXY 163


PIMCD2013-python, Publicacin 1.0

la mscara circular. Esto se logra con el ltimo if del cdigo. Finalmente se muestran las representaciones de la
amplitud y la fase.
En la figura se muestra la mscara de amplitud a la izquierda y a la derecha la fase en el plano XY. Es destacable
el decaimiento de la misma de con la distancia.

amplitud fase
300 300

200 200

100 100
y(m)

y(m)
0 0

100 100

200 200

300 300

300 200 100 0 100 200 300 300 200 100 0 100 200 300
x(m) x(m)

amplitud fase
300 300

200 200

100 100
y(m)

y(m)

0 0

100 100

200 200

300 300

300 200 100 0 100 200 300 300 200 100 0 100 200 300
x(m) x(m)

12.2.5 Haz de Gauss

Un haz gaussiano es aquel en el que cualquier plano normal a la direccin de propagacin a distribucin de
intensidades del campo elctrico se ajusta a una gaussiana. As sea una gaussiana de varianza w, centrada en el
punto (x0,y0). As se define amplitud como
(0 )2 (0 )2
( 2
2
2
2
)
=
Mientras que la fase vale

= ( sin() sin()+ cos() sin())

164 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

De este modo, el haz queda caracterizado por el producto de las mismas

Esta ltima ecuacin desglosada en fase y amplitud es la que se implementa en la funcin haz_gauss
A continuacin se muestra una representacin del perfil de intensidades para un haz gaussiano.

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)
12.2.6 Vrtice

Las estructuras tipo vrtice son aquellas en las que la fase se comporta linealmente con la variable angular (en
coordenadas cilndricas), esto es (, , ) = , siendo m el orden del vrtice.
Ahora veremos cmo se puede llamar a esta funcin

12.2. Clase fuentesXY 165


PIMCD2013-python, Publicacin 1.0

amplitud mvortice =3 fase


300 300
200 200
100 100
y(m)

y(m)
0 0
100 100
200 200
300 300
300 200 100 0 100 200 300 300 200 100 0 100 200 300
x(m) x(m)
0.00 0.15 0.30 0.45 0.60 0.75 0.90 2.4 1.6 0.8 0.0 0.8 1.6 2.4

Ahora N vrtices
Vortices
(1) (2) (3) (4) (5)

12.2.7 Haz de Laguerre

Similarmente a los haces gaussianos se definen los modos de Laguerre como aquellos haces en los que el perfil de
intensidades sigue una distribucin de modo de Laguerre, es decir una distribucin
2

2()
2

() 2
2 +(2++1)() (1) ( ()2 )
/2 22
(, , ) = ( )
()2

La funcin haz_laguerre realiza exactamente este cometido, pero desglosa el producto en pequeos trminos
t1,t2,t3,t4.
As se pueden extraer la amplitud y la fase del haz y ser representadas anlogamente a los casos anteriores.

166 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

amplitud n =2,k =2 fase


300 300
200 200
100 100
y(m)

y(m)
0 0
100 100
200 200
300 300
300 200 100 0 100 200 300 300 200 100 0 100 200 300
x(m) x(m)
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 2.4 1.6 0.8 0.0 0.8 1.6 2.4

Finalmente mostrados distintos modos de Laguerre para diferentes pares (l,p). Al aumentar l aumenta el nmero
de anillos, as como la intensidad local se reduce si se incrementa p.

(0,0) (1,0)
amplitud (2,0) (3,0)

(0,1) (1,1) (2,1) (3,1)

(0,2) (1,2) (2,2) (3,2)

(0,3) (1,3) (2,3) (3,3)

12.2. Clase fuentesXY 167


PIMCD2013-python, Publicacin 1.0

(0,0) (1,0)
fase (2,0) (3,0)

(0,1) (1,1) (2,1) (3,1)

(0,2) (1,2) (2,2) (3,2)

(0,3) (1,3) (2,3) (3,3)

12.2.8 Aberraciones: Haces de Zernike

Los frentes de onda de un haz de luz pueden presentar perturbaciones, debidas a la propia propagacin en el medio
o introducidas por elementos pticos estas perturbaciones reciben el nombre de aberraciones del haz. La forma
ms comn de clasificar las aberraciones es en las llamadas aberraciones de Zernike, las cuales hacen uso de la
base de polinomio que les da nombre, polinomios de Zernike. Estos polinomios estn definidos sobre el crculo
unidad, en trminos de dos variables radial, y acimutal, junto con dos parmetros, (m,n) que representan el
orden del Zernike. As se define si n es par

(, ) = () cos( )

Mientra que si n es impar

(, ) = () sin( )

Donde
()/2
(1) ( )!
() = 2
! (( + )/2 )! (( )/2 )!
=0

Esto ha sido implementado en la clase fuentesXY mediante la funcin fZernike, con argumentos, n, m y radio
La gran utilidad de los polinomios de Zernike es que permiten expresar cualquier aberracin del frente de ondas

como una suma de trminos . As, si son los coeficientes del polinomio de Zernike, cualquier aberracin
en la fase podr escribirse como


=

Por tanto, haciendo uso de los polinomios definidos con fZernike se determina la aberracin del frente de ondas
calculando la variacin en la fase.

168 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

As se ha obtenido mediante una representacin cualquiera, la amplitud y la fase de un haz aberrado.

1000
amplitud 1000
fase

500 500
y(m)

y(m)
0 0

500 500

10001000 500 0 500 1000 10001000 500 0 500 1000


x(m) x(m)
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 2.4 1.6 0.8 0.0 0.8 1.6 2.4

Existen distintos pares (, ) de especial importancia en ptica cuyo trmino de Zernike asociado recibe nombre
propio. Estos son:
(0, 0) Pistn.
(1, 1) Tilt.
(2, 2) Astigmatismo.
(2, 0) Desenfoque.
(4, 0) Aberracin Esfrica.
A continuacin se muestra una representacin en fase y amplitud de las aberraciones ms importantes

12.2. Clase fuentesXY 169


PIMCD2013-python, Publicacin 1.0

polinomios de Zernike (n,m)


(0,0)

(1,-1) (1,1)

(2,-2) (2,0) (2,2)

(3,-3) (3,-1) (3,1) (3,3)

(4,-4) (4,-2) (4,0) (4,2) (4,4)

12.3 Clase mascarasXY

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto
Para poder realizar tratamientos numricos de difraccin, es necesario realizar un sistema de mscaras que modi-
fiquen el haz de entrada. En esta seccin veremos las mscaras en el plano (X,Y) que hemos definido, mediante la
clase mascaraXY. Las mscaras pueden ser de mltiples tipos, sin embargo en este captulos nos limitaremos a
mscaras planas.
Adems de las tcnicas de diseo de mscaras veremos ejemplos de cmo utilizarlas. Adicionalmente, en el tema
de Difraccin se muestra como la propagacin de la luz que es modificada por estas mscaras.

170 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

Contenidos de este captulo:


Funcionamiento de la clase mascarasXY
Operaciones con mscaras
Sumar Mscaras
Restar Mscaras
Rotar mscaras
Rendija
Doble Rendija
Cuadrados y rectngulos
Crculos y elipses
Anillo
Cruz
Dos niveles
Imagen
Escala de grises
Lentes
Axicn
Espiral de Arqumedes
Espiral de Laguerre
Red Forked
Superficie rugosa

Herramientas utilizadas en este tutorial:


Archivo con las funciones principales de campos mascarasXY.py
Archivo con las funciones principales de fuentes fuentesXY.py
Archivo con las funciones principales de mascaras mascarasXY.py
Descarga de archivos:
Clase mscaras con las funciones de los distintos tipos de mscara mascarasXY.py
Archivo con el ejemplo de una rendija ejemplo_rendija.py
Archivo con el ejemplo de una doble rendija ejemplo_doble_rendija.py
Archivo con el ejemplo de una mscara cuadrada ejemplo_cuadrado.py
Archivo con el ejemplo de una mscara circular ejemplo_circulo.py
Archivo con el ejemplo de una mscara imagen ejemplo_imagen.py
Archivo con el ejemplo de una mscara binaria ejemplo_dosNiveles.py
Ejemplo de una escala de grises ejemplo_escala_grises.py
Ejemplo de una mscara tipo espiral de Arqumedes ejemplo_espiral.py
Ejemplo de una mscara tipo espiral de Laguerre ejemplo_espiral.py
Archivo con el ejemplo de una lente ejemplo_lentes.py
Ejemplo de una red tipo Forked ejemplo_red_forked.py
Archivo con el ejemplo de una superficie rugosa ejemplo_superficie_rugosa.py
Contenidos de los archivos
mascarasXY.py :
rendija() Simula una mscara tipo rendija plana.
dobleRendija() Define una doble rendija.
cuadrado() Simula una mscara cuadrada con transmitancia en el interior del cuadrado.

12.3. Clase mascarasXY 171


PIMCD2013-python, Publicacin 1.0

circulo() Simula una mscara circular con transmitancia en el interior del crculo.
anillo() Define una mscara anular con transmitancia nicamente en la corona del anillo, no per-
mitiendo el paso de luz ni en el centro ni en el exterior del anillo.
cruz() Simulacin de una mscara con forma de cruz con transmitancia unidad en el interior de la
misma.
dosNiveles() Discretiza una imagen en dos niveles de intensidad definidos.
imagen() Permite modificar algunas propiedades de imgenes tales como normalizar su intensidad,
seleccionar un calar de color, invertir la imagen, entre otros.
escalaGrises() Construye una escala de grises.
lente() Determina la amplitud y la fase de la luz al atravesar una lente.
axicon() Modela una lente tipo axicon.
redForked() Modela una red tipo Forked.
rugosidad() Simula una superficie rugosa.

12.3.1 Funcionamiento de la clase mascarasXY

Las mscaras estn guardados en una clase, muy sencilla, que sirve de repositorio de funciones, cada una de ellas,
rellena la variable self.u que es la matriz donde se almacena la mscara en forma de coeficientes de transmisin
t(x,y).
Adicionalmente a las mscaras, se incluyen 4 operaciones sobre las mscaras (__add__, __sub__, __mul__, __ro-
tar__). Las tres primeras son operaciones son predefinidas de la clase y actuan sobre los simbolos +,-,*.
Las mscaras que se han definido dentro de la clase mascarasXY se muestran a continuacin y representan distintos
tipos de mscaras bidimensionales que habitualmente se emplean en ptica, tales como rendijas, dobles rendijas,
mscaras cuadradas, circulares, anillo, en cruz, entre otras.
La mayora de las mscaras definidas tienen la forma:
def nombre(self, r0, parametros, angulo):

En este caso r0 representa la posicin (x,y) de la mscara, parametros son los parmetros propios de la mscara,
como el tamao, y angulo es la rotacin.

12.3.2 Operaciones con mscaras

Para facilitar la creacin de nuevas mscaras, se han incluido las operaciones sobre las mscaras __add__,
__sub__, __mul__, __rotar__, ya definidas, las cuales respectivamente, suman, restan multiplican y rotan. Para
la definicin de estas funciones se requiere de la clase macarasXY y camposXY.
Hay otra operacin __rotar__ (no se implementa a travs de un operador) y que se utiliza en las definiciones de
las mscaras para rotarlas.

Sumar Mscaras

En este primer ejemplo veremos la suma de dos mascaras una cuadrada y otra circular. El cdigo para definir
este tipo de mscaras se explica ms abajo. La estructura de la implementacin en python consiste en declarar
las dos mscaras, t1, t2 y posteriormente sumarlas t2=t2+t1. Finalmente se dibujan a fin de obtener una
representacin.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea

172 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

# Fecha 2013/10/24 (version 1.0)


# Licencia: GPL
#-------------------------------------
"""Ejemplo de uso de mascaras"""

import sys
sys.path.append(../)
from mascarasXY import *

def sumar_mascaras():
ndatos = 128
tamano = 250 * um
x = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y = sp.linspace(-tamano / 2, tamano / 2, ndatos)
wavelength = 0.6328 * um
#Mascara 1
t1 = mascaraXY(x, y, wavelength)
t1.cuadrado(r0 = (-50 * um, 0 * um), size = (50 * um, 50 * um), angulo = 0 * grados)
#Mascara 2
t2 = mascaraXY(x, y, wavelength)
t2.circulo(r0 = (50 * um, 0 * um), radius = (25 * um, 25 * um), angulo = 0 * grados)
#suma
t3 = t2 + t1
#funcion para dibujar varias mascaras a la vez
dibujar_varios_campos(campos=(t1,t2,t3),titulos=(mascara 1,mascara 2, suma))

sumar_mascaras()
plt.show()

mascara 1 mascara 2 suma


100 100 100
50 50 50
0 0 0
50 50 50
100 100 100
100 50 0 50 100 100 50 0 50 100 100 50 0 50 100

0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0

En este primer ejemplo incluimos todo el cdigo del archivo. A partir de ahora solo incluiremos la funcin. Es
decir, quitaremos el cabecero, las importaciones necesarias, que en estos ejemplos son
import sys
sys.path.append(../)
from mascarasXY import *

y la llamada final a la funcin


sumar_mascaras()
plt.show()

12.3. Clase mascarasXY 173


PIMCD2013-python, Publicacin 1.0

Hay que tener cuidado qu ocurre cuando las dos mscaras solapan: el coeficiente de transmisin no puede ser
superior a 1 (no son medios activos). Si nos fijamos en mascaraXY.__add__ esto est considerado.

mascara 1 mascara 2 suma


100 100 100
50 50 50
0 0 0
50 50 50
100 100 100
100 50 0 50 100 100 50 0 50 100 100 50 0 50 100

0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0

Restar Mscaras

Con dos mscaras tambin se puede quitar la parte comn entre ellas. El procedimiento a seguir en python es
anlogo al caso de la suma. Nuevamente las mscaras cuadrada y circular se definirn ms abajo en esta seccin.

mascara 1 mascara 2 resta


30 30 30
20 20 20
10 10 10
0 0 0
10 10 10
20 20 20
30 30 30
30 20 10 0 10 20 30 30 20 10 0 10 20 30 30 20 10 0 10 20 30

0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0

Rotar mscaras

En este ejemplo se genera un rectngulo (ya veremos como) y se cambia su orientacin representando as mscaras
rectangulares a 0, 45 y 90 grados. Nuevamente las mscaras cuadrada y circular se definirn ms abajo en esta
seccin.

174 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

60
0 grados 60
45 grados 60
90 grados
40 40 40
20 20 20
0 0 0
20 20 20
40 40 40
60 60 60
60 40 20 0 20 40 60 60 40 20 0 20 40 60 60 40 20 0 20 40 60

0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0

El uso de la clase mscara se puede ver en el mdulo correspondiente. Aqu pasamos a ver diversas mscaras que
luego se pueden utilizar en difraccin y en otros ejemplos de ptica.

12.3.3 Rendija

Una rendija consiste en una regin del plano de la mscara comprendida entre dos rectas paralelas, tal que en
dicha regin se permite el paso de la luz, fuera de esta zona, la luz no atraviesa la mscara. As dentro de la clase
mascarasXY se ha definido la funcin rendija. En ella se dan de argumentos el centro de la misma x0, la
anchura de la rendija um y el ngulo de inclinacin en grados. El cdigo define dos rectas verticales xmin y max,
cuyo espacio abarcado determina el paso de luz, la rendija. Estas dos rectas son verticales, por ello se aplica la
rotacin para describir la inclinacin de la rendija. Finalmente el if, determina la regin del plano que puede ser
atravesada por la luz.
A modo de ejemplo se muestra la representacin de una rendija con una anchura 100 um.

12.3. Clase mascarasXY 175


PIMCD2013-python, Publicacin 1.0

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)
12.3.4 Doble Rendija

Anlogamente con el caso de una rendija, se puede definir una doble rendija como una composicin o suma de dos
rendijas simples. El estudio de dobles rendijas es de vital importancia en ptica constituyendo una de las bases
de la difraccin y a interferometra. Obsrvese como el cdigo Python de la funcin doblerendija consiste en una
suma de dos rendijas simples separadas una distancia definida por el argumento separacin.
As se obtiene un ejemplo de representacin de la doble rendija:

176 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

1.0
10 0.9
0.8
5 0.7
0.6
y(m)

0 0.5
0.4
5 0.3
0.2
10 0.1

10 5 0 5 10 0.0
x(m)
12.3.5 Cuadrados y rectngulos

Otro tipo de mscara de amplio uso en ptica son las mscaras cuadradas o rectangulares. Estas mscaras con-
sisten en una regin del espacio comprendida entre cuatro rectas paralelas dos a dos, tales que los ngulos que
forman son todos rectos, de modo que la transmitancia en cualquier punto interior a dicha regin es la unidad. La
implementacin del cdigo de python supone la definicin del centro del cuadrado/rectngulo, as como el tamao
de sus lados. Finalmente se define una rotacin y los puntos de transmitancia unidad.
Su representacin queda as

12.3. Clase mascarasXY 177


PIMCD2013-python, Publicacin 1.0

cuadrado rectangulo
100 100

50 50

0 0

50 50

100 100
100 50 0 50 100 100 50 0 50 100

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

12.3.6 Crculos y elipses

De manera anloga a la mscara cuadrada, se define una mscara circular como aquella que permite el paso de luz
para aquellos rayos que incidan en el interior del crculo o elipse. Para ello se define el origen del crculo con r0
y los semiejes de la elipse radiox y radioy, en caso de ser iguales, se obtiene un crculo. La lnea de cdigo
ipasa = (Xrot - x0) * * 2 / radiusx * * 2 + (Yrot - y0) * * 2 / radiusy * * 2 < 1

establece el paso de luz nicamente en el interior del crculo o elipse.


As resulta la representacin de la mscara

circulo elipse
100 100

50 50

0 0

50 50

100 100
100 50 0 50 100 100 50 0 50 100

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

La elipse utiliza la misma programacin y se cambian los parmetros.


t1.circulo(r0 = (0 * um, 0 * um), radius = (100 * um, 50 * um), angulo = 45 * grados)

178 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

12.3.7 Anillo

Una estructura tipo anillo consiste en dos regiones circulares o elpticas concntricas, tales que el paso de luz
sucede nicamente en la regin comprendida entre ambas. Para su implementacin se definen dos vectores con
dos compontes cada uno, llamados radio1 y radio2 tales que sus componentes representan los semiejes de
las elipses interior y exterior. Nuevamente el ngulo theta describe la inclinacin del anillo. Por tanto se definen
dos crculos o elipses concntricos tales que se permite el paso de luz en su interior, estos estn binarizados, es
una mscara o matriz con 1 en aquellos puntos interior y cero en los exteriores. Para construir la estructura tipo
anillo, se restan ambos crculos (mscaras), de este modo que la corona es la nica regin con unos en su interior.
Como resultado se tiene

anillo otro tipo


100 100

50 50

0 0

50 50

100 100
100 50 0 50 100 100 50 0 50 100

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Tambin se pueden hacer figuras ms interesantes si no se mantiene que el tamao del anillo 2 sea mayor que el
anillo uno, como en el segundo ejemplo, donde
t1.anillo(r0 = (0 * um, 0 * um), radius1 = (50 * um, 100 * um), radius2 = (100 * um, 50 * um), ang

12.3.8 Cruz

Las mscaras tipo cruz se pueden interpretar como la superposicin de dos mscaras tipo cuadrado rotadas entre
s 90 permitiento el paso de luz nicamente en la regin interior a la cruz. Por tanto para la implementacin de
este tipo de mscara, bastar con definir las dos mscaras cuadradas, mediante su origen (comn) r0 y los lados
de cada cuadrado. De este modo se definen t1 y t2 como dos mscaras cuadradas rotadas entre s 90. La suma de
las matrices de cada mscara, da lugar a la mscara de cruz, no obstante hay puntos en la matriz suma t1+t2 con
transmitancia mayor que la unidad por ello en la ltima lnea de cdigo se redefinen todos los puntos con valor
mayor a uno, reescalndolos a la unidad.
As queda representada como

12.3. Clase mascarasXY 179


PIMCD2013-python, Publicacin 1.0

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)
12.3.9 Dos niveles

Esta funcin discretiza una imagen en dos niveles de intensidad definidos por los argumentos nivel1 y nivel2. Esta
discretizacin se hace acorde a un nivel de corte o de referencia, xcorte, de modo que todos aquellos puntos de
la imagen con intensidad menor xcorte adquieren el valor nivel1, as mismo, los niveles mayores a xcorte
son asignados con intensidad nivel2. La estructura del programa realiza este proceso en dos lneas, la primera
crea una matriz de nivel1 con el mismo tamao que la imagen, X. La segunda lnea asigna la intensidad nivel2
a aquellas columnas de la matriz con nivel de intensidad mayor que el nivel de corte, xcorte.
As resulta

180 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

0.250
100 0.225
0.200
50 0.175
0.150
y(m)

0 0.125
0.100
50 0.075
0.050
100 0.025

100 50 0 50 100 0.000


x(m)
12.3.10 Imagen

Si no sabemos crear una mscara, o resulta demasiado complicada la podemos dibujar en otro programa, como
Gimp, Inkscape. Entonces la podemos cargar como mscara a travs de la funcin imagen. Para ello necesi-
tamos la librera Image especfica de python para trabajar con imgenes. Posteriormente se carga la imagen
especificada con el argumento nombre, para ello se hace uso de dos funciones especficas cargarImagen y
visualizarimagen, las cuales cargar una imagen desde un archivo con localizacin especfica, y la visuali-
zan respectivamente. No entramos a explicar el funcionamiento de estas dos funciones, estando definidas en una
clase externa imagenesLM, y sin poseer mayor dificultad. Image.open(nombre) abre la imagen pero no la
muestran en pantalla, sino que la almacena como variable im, recurdese que la imagen ya est siendo visualizada,
puesto que se emple visualizarImagen, en la lnea anterior. im.transpose(1), transpone la imagen,
intercambiando filas por columnas. Mediante im.split() se descompone la imagen en colores extrayendo un
array con las componentes RGB de la imagen. Debido a que no interesa el color sino la intensidad, se selecciona la
componente de color canal especificada en el argumento de nuestra funcin imagen con colores[canal].
El resto del programa son if y suponen una serie de condiciones. El primero, cambia el tamao de la imagen
manteniendo la relacin de aspecto permitiendo adems una rotacin de la imagen. Para ello se extraen las di-
mensiones de la imagen y se definen dos arrays para finalmente generar un mallado y aplicar una rotacin. El
siguiente if plantea una inversin de intensidad, ello lo logra restando la intensidad mxima de la imagen menos
la intensidad de la imagen en cada punto y generando as una imagen invertida en intensidades. Finalmente, el
ltimo if, normaliza las intensidades a la unidad.
Veamos un ejemplo de sencillo de cmo cargar una imagen.

12.3. Clase mascarasXY 181


PIMCD2013-python, Publicacin 1.0

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)
12.3.11 Escala de grises

La funcin escalaGrises construye un vector con el nmero de niveles de gris establecidos en el argumento
NumNiveles, con intensidades mxima nivelMax y mnima nivelMin. Para ello se define un vector t de
ceros a fn de generar la estructura de nuestro vector salida, sobre este vector sobrescribiremos los datos finales.
Posteriormente, se define un array, niveles con intensidades entre nivelMin y nivelMax del tamao del vector
x definido en la clase mascarasXY. As mismo, otro vector xpos de nmeros enteros con valores entre 0 y el
entero ms prximo a la longitud de x, con numNiveles + 1 componentes. El objetivo de este vector ser de-
terminar las filas de t a las que se asocia cada nivel de gris. Esto ltimo se logra mediante el bucle for, asociando
a las componentes de t comprendidas entre los valores de dos compontes consecutivas de xpos el valor de gris
especificado.
De este modo se obtiene la figura

182 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)
12.3.12 Lentes

Mediante la funcin lente calculamos la fase y la amplitud de la luz al atravesar una lente con astigmatismo. As
sean f1 y f2 las focales, de modo que la fase, de la luz viene determinada por
As mismo, la transmitancia se supone determinada por la superficie de la lente, la cual modelamos mediante
una mscara circular. Por tanto se define el centro de la lente, con r0 y la focal f1, f2, para definir la mscara
circular/elptica con orientacin determinada por el ngulo especificado en el argumento de la funcin conforme
se describi en la seccin de la mscara crculo. De este modo, queda definida la amplitud mediante la mscara.
Finalmente, para la fase basta implementar la ecuacin anterior.
En los siguientes ejemplos se muestra una representacin de la amplitud y la fase queda

12.3. Clase mascarasXY 183


PIMCD2013-python, Publicacin 1.0

amplitud fase
400 400

200 200
y(m)

y(m)
0 0

200 200

400 400

400 200 0 200 400 400 200 0 200 400


x(m) x(m)

amplitud fase
400 400

200 200
y(m)

y(m)

0 0

200 200

400 400

400 200 0 200 400 400 200 0 200 400


x(m) x(m)
En el caso de una lente con estigmatismo, simplemente es cambiar las focales
t1.lente(r0 = (0 * um, 0 * um), radius = (500 * um, 250 * um), focal = (50 * mm, 12.5 * mm))

12.3.13 Axicn

Un axicn es un tipo particular de lente con superficie cnica. Su funcin principal es la de transformar haces co-
limados en anillos. La funcin axicon con argumentos, radio y altura del cono, as como ndice de refraccin
del vidrio, calcula la intensidad y la fase de la luz al atravesar dicho elemento ptico. As una vez definidos el
origen r0, el vector de onda k y la distancia, r, de la generatriz al eje del cono, se implementa la superficie del
elemento ptico como h en trminos de r. Definida la superficie del axicon, queda imponer una serie de restric-
ciones tales como que la altura, h no puede ser nunca negativa, esto es, el axicon, no se extiende en el espacio
objeto. As mismo, se determina la regin de transmitancia de la luz como aquella en la que incide la luz sobre el
axicon, es decir, nicamente son vlidos los puntos de la base del axicon, r<radius. Finalmente se determina
la fase con la relacin

184 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

..:math:: e^{ik(n-1)h}
En el ejemplo se muestra la amplitud y la fase a la salida de un axicon

amplitud fase
100 100

50 50
y(m)

y(m)
0 0

50 50

100 100
100 50 0 50 100 100 50 0 50 100
x(m) x(m)
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 2.4 1.6 0.8 0.0 0.8 1.6 2.4

En el caso de una lente con estigmatismo, simplemente es cambiar las focales


t1.lente(r0 = (0 * um, 0 * um), radius = (500 * um, 250 * um), focal = (50 * mm, 12.5 * mm))

12.3.14 Espiral de Arqumedes

Se muestra cmo desarrollar la espiral de Arqumedes. Resulta un poco complicado entender como se desarrolla
(yo tampoco lo entiendo),

100 potencia 1 100 potencia 2


50 50

0 0

50 50

100100 50 0 50 100 100100 50 0 50 100

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

12.3. Clase mascarasXY 185


PIMCD2013-python, Publicacin 1.0

12.3.15 Espiral de Laguerre

Esta funcin hace uso de las clases fuentesXY as como de mscaras. Por defecto la
EspiralLaguerreGauss obtiene la espiral en amplitud, salvo que se especifique lo contrario. Se im-
porta la clase fuentesXY, y se genera un haz tipo Laguerre conforme se vio en la seccin de fuentes. A
continuacin definimos el radio del haz que se va a representar siendo este la mitad del cuadrado de represen-
tacin. Resta implementar la espiral, para ello se llama a la clase mascarasXY, y se implemente la funcin
crculo ya definida anteriormente. Posteriormente se extrae la fase con angle y se normalizan las intensidades,
finalmente se realiza un binarizacin. Alternativamente se puede especificar la fase en el argumento de la funcin,
el ltimo if es el encargado de esta tarea.

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)

186 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

amplitud fase
100 100

50 50
y(m)

y(m)
0 0

50 50

100 100
100 50 0 50 100 100 50 0 50 100
x(m) x(m)
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.4 0.8 1.2 1.6 2.0 2.4 2.8

Tambin se puede hacer de fase, cambiando el tipo


t.EspiralLaguerreGauss(tipo = fase, l = 4, r0 = (0 * um, 0 * um), w0 = 20 * um, z = 0.01 * um)

12.3.16 Red Forked

Una red tipo Forked es un tipo de mscara binaria de tipo franjas en la que existe una macla, punto en el cual un
conjunto de franjas convergen. Este tipo de red se puede definir mediante el siguiente cdigo.
El resultado es

12.3. Clase mascarasXY 187


PIMCD2013-python, Publicacin 1.0

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)
12.3.17 Superficie rugosa

La superficies rugosas son de gran importancia prctica en ptica pues muchas de las superficies tienen un cierto
grado de rugosidad. La rugosidad es un proceso aleatorio que se caracteriza a travs de ciertos parmetros como
la altura media y la longitud de correlacin, que puede ser distinta en las direcciones x e y, por los procesos de
fabricacin de las superficies. En el siguiente cdigo se muestra un ejemplo de cmo generar una superficie rugosa
con unos parmetros dados.
La fase y amplitud quedan representadas como sigue

188 Captulo 12. Mdulos de ptica


PIMCD2013-python, Publicacin 1.0

100 2.4

1.6
50
0.8
y(m)

0 0.0

0.8
50
1.6

100 2.4

100 50 0 50 100
x(m)
topografia
1.6
100
1.2

50 0.8

0.4
y(m)

0
0.0

50 0.4

0.8
100
1.2
100 50 0 50 100
x(m)

12.3. Clase mascarasXY 189


PIMCD2013-python, Publicacin 1.0

190 Captulo 12. Mdulos de ptica


CAPTULO 13

Difraccin en campo cercano

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto

Contenidos de este captulo:


Introduccin
Programacin
Difraccin por una abertura cuadrada
Difraccin por una abertura cuadrada: varias distancias
Difraccin por una abertura circular
Difraccin por un borde
Difraccin por una doble rendija
Difraccin por una lente
Difraccin por una lente binaria

Herramientas utilizadas en este tutorial:


Mdulo de campos camposXY.py.
Mdulo de fuentes fuentesXY.py.
Mdulo de mscaras mascarasXY.py.
Archivos necesarios para esta seccin:
Ejemplo de difraccin en campo cercano por una mscara cuadrada difraccion_cuadrado.py.
Ejemplo de difraccin en campo cercano por una mascara cuadrada a varias distancias
difraccion_cuadrado_varias_distancias.py.
Ejemplo de difraccin en campo cercano por un crculo difraccion_circulo.py.
Ejemplo de difraccin en campo cercano por crculo a varias distancias
difraccion_circulo_varias_distancias.py.
Ejemplo de difraccin en campo cercano por un borde difraccion_borde.py.
Ejemplo de difraccin en campo cercano por un borde a varias distancias
difraccion_borde_varias_distancias.py.
Ejemplo de difraccin en campo cercano por una doble rendija difraccion_doble_rendija.py.
Ejemplo de difraccin en campo cercano por una lente difraccion_lente.py.
Ejemplo de difraccin en campo cercano por una lente binaria difraccion_lente_binaria.py.

ejemplos de visualizacin 3D

191
PIMCD2013-python, Publicacin 1.0

Ejemplo de difraccin 3D en campo cercano por una lente difraccionlente3D_1.py.


Ejemplo de difraccin 3D en campo cercano por una lente difraccionlente3D_2.py.

13.1 Introduccin

En esta seccin analizaremos la difraccin en campo cercano bajo la aproximacin de Fresnel.


Segn esta ecuacin, el campo propagado a una cierta distancia de un elemento difractor, se calcula a travs de
la siguiente integral

1 2 2
E0 (, ) 2 [() +() ]

E(, , ) =

donde E0 (, ) = (, )E (, ) es el campo a la salida del elemento difractor que, bajo la aproximacin


de elemento delgado se obtiene como la multiplicacin del campo incidente E (, ) por el coeficiente de
transmisin de la mscara difractora (, )

13.2 Programacin

Para el desarrollo de los ejemplos de esta seccin hemos programado numricamente el clculo de esta integral a
partir de &apos;fast-Fourier-transform based direct integration (FFT-DI) method&apos; segn el artculo de Shen
y Wang 1 . Este algoritmo lo hemos implementado en la clase camposXY (que es heredada por mascarasXY y
fuentesXY) con el nombre de RS (a partir de Rayleigh-Sommerfed, que es una versin ligeramente mejorada de
la integral de Fresnel).
Por consiguiente, si tenemos un campo, mscara o fuente, tendr un mtodo RS que podemos aplicar. Si tenemos
un campo de tamao NxM, el resultado de la propagacin ser tambin NxM, aunque existe un parmetro de
amplificacin que nos permite calcular tamaos del plano de observacin mayores (jN)x(jM).
La ventaja que tiene es que nos devuelve un parametro de calidad que nos informa si la aproximacin se ha
realizado debidamente. Si el parmetro de calidad (almacenado en self.calidad) tiene un valor superior a 1, la
propagacin se ha realizado convenientemente.
def RS(self, z = 10 * mm, newField = True, tipo=z, xout = None, yout = None):
"""Metodo de Fast-Fourier-Transform para la integracion numerica
de la Formula de la difraccion de Rayleigh-Sommerfeld.
Extraido de Applied Optics vol 45 num 6 (1102-1110) - 2006
- z es la distancia (si es <0 se realiza la propagacion inversa
- newfield, si es False el calculo se queda en la instancia, si es True se genera
- xout, yout se utilizan para decir las coordenadas de salida (para la amplificaci

el tamao del pixel debe ser igual, aunque la mscara puede tener distinto tamao
"""

xin = self.x; yin = self.y


x1 = self.x[0]; y1 = self.y[0]
xin1 = self.x[0]; yin1 = self.y[0]

if xout == None:
xout = self.x
if yout == None:
yout = self.y

nx = len(xout); ny = len(yout)
1 Fabin Shen and Anbo Wang &quot;Fast-Fourier-transform based numerical integration method for the RayleighSommerfeld diffraction

formula&quot; Applied Optics vol. 45 num 6. pp. 1102-1110 (2006).

192 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

dx = xout[1] - xout[0]; dy = yout[1] - yout[0]

#parametro de calidad
dr_real = sp.sqrt(dx ** 2 + dy ** 2)
rmax = sp.sqrt((xout ** 2).max() + (yout ** 2).max())
dr_ideal = sp.sqrt(self.wavelength ** 2 + rmax ** 2 + 2 * self.wavelength * sp.sqr
self.calidad = dr_ideal / dr_real
#siempre que se hace un clculo se informa por consola de la calidad de este.
if(self.calidad > 1):
print Buena aproximacion: factor , self.calidad
else:
print Necesita un muestreo mayor: factor, self.calidad

#matriz computada
W = 1
U = sp.zeros((2 * ny - 1, 2 * nx - 1), dtype = complex)
U[0:ny, 0:nx] = W*self.u #el transpose lo he cambiado porque daba problemas para
xext = x1 - xin[::-1] #da la vuelta
xext = xext[0:-1]
xext = sp.concatenate((xext, self.x - xin1))
yext = y1 - yin[::-1]
yext = yext[0:-1]
yext = sp.concatenate((yext, self.y - yin1))
Xext, Yext = sp.meshgrid(xext, yext)

#permite calcula la propagacion y la propagacion inversa, cuando z<0.


if z > 0:
H = kernelRS(Xext, Yext, self.wavelength, z, tipo=tipo)
else:
H = kernelRSinversa(Xext, Yext, self.wavelength, z, tipo=tipo)

#calculo de la transformada de Fourier


S = ifft2(fft2(U) * fft2(H)) * dx * dy #el transpose lo he cambiado porque daba p
Usalida = S[ny - 1:, nx - 1:] #hasta el final

#los calculos se pueden dejar en la instancia o crear un nuevo campo (ms usual).
if newField == True:
campoSalida = campoXY(self.x, self.y, self.wavelength)
campoSalida.u = Usalida / z
campoSalida.calidad=self.calidad
return campoSalida
else:
self.u = Usalida / z

Todos los clculos realizados en esta seccin sern nmericos, lo cual nos da una gran ventaja computacional:
solamente tenemos que describir la fuente y la mscara, y tendremos el campo difractado a una distancia z.

13.3 Difraccin por una abertura cuadrada

Como primer ejemplo realizaremos la propagacin en campo cercano de una abertura bidimensional cuadrada.
Utilizaremos este ejemplo para explicar el proceso.
Se definen los parmetros dimensionales de las mscaras y los parmetros pticos (longitud de onda).
Se crea una fuente de iluminacin a travs de la clase fuenteXY().
Se crea una mscara con las dimensiones apropiadas.
Se realiza la Aproximacin de elemento delgado: u2 = u1 * t1
se realiza la propagacin: u3 = u2.RS(z = z_difraccion, newField = True)
Se dibuja el resultado.

13.3. Difraccin por una abertura cuadrada 193


PIMCD2013-python, Publicacin 1.0

El cdigo empleado y las grficas resultantes son las siguientes.


#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

import sys
sys.path.append(../)
sys.path.append(../general/)

from camposXY import * #@UnusedWildImport


from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccion_cuadrado():
#tamano de area de visualizacion
tamano = 100 * um
ndatos = 256
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
#longitud de onda
lambda0 = 0.6238 * um

#fuente de iluminacion
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

#mascara
radio = 20 * um
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.cuadrado(r0 = (0 * um, 0 * um), size = (60 * um, 60 * um), angulo = 0 * grados)
u2 = u1 * t1

#plano de observacion
z_difraccion = 500*um

#propagacion y acondicionamiento grafica


u3 = u2.RS(z = z_difraccion, newField = True)
texto = "z=%d $\mu m$" % (z_difraccion)

dibujar_varios_campos(campos=(u2,u3),titulos=(cuadrado, texto))

difraccion_cuadrado()
plt.show()

194 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

cuadrado z=500 m
40 40

20 20

0 0

20 20

40 40
40 20 0 20 40 40 20 0 20 40

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

13.4 Difraccin por una abertura cuadrada: varias distancias

En el ejemplo anterior se vislumbra el comportamiento general en campo cercano: la distribucin de intensidad se


asemeja algo al objeto, pero los efectos difractivos producen fluctuaciones de intensidad que aumentan a medida
que nos separamos del objeto difractor. Para ver esto de forma ms rigurosa, en el siguiente ejemplo se muestra
la distribucin de intensidad en varios planos. Para ello generamos dos funciones, mascara_cuadrado() que
calcula el campo inicial
def mascara_cuadrado():
tamano = 25 * um
ndatos = 256
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
lambda0 = 0.6238 * um

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);


u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t1.cuadrado(r0 = (0 * um, 0 * um), size = (20 * um, 20 * um), angulo = 0 * grados)

u2 = u1 * t1
return u2

y otra que recibe el campo u2 y genera un bucle con difrerentes distancias


def difraccion_varias_posiciones(u2, distancias):

plt.figure(figsize=(12,6))

num_figuras = len(distancias)

filas = [1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 4, 4, 4, 4, 5, 4]
columnas = [1, 2, 3, 2, 3, 3, 3, 3, 3, 5, 3, 3, 4, 4, 3, 4]

extension=[u2.x[0],u2.x[-1],u2.y[0],u2.y[-1]]
plt.subplot(filas[num_figuras], columnas[num_figuras], 1)

13.4. Difraccin por una abertura cuadrada: varias distancias 195


PIMCD2013-python, Publicacin 1.0

h1 = plt.imshow(abs(u2.u) ** 2, interpolation = bilinear,


origin = lower, extent = extension)
h1.set_cmap("gist_heat")
plt.title(umascara)

for z, i in zip(distancias, range(num_figuras)):


#difraccion a la distancia estipulada
u3 = u2.RS(z = z, newField = True)
texto = "z=%d $\mu m$" % (z)
#carga de los dibujos
plt.subplot(filas[num_figuras], columnas[num_figuras], i + 2)
plt.axis(off)
plt.title(texto)
h1 = plt.imshow(abs(u3.u) ** 2, interpolation = bilinear,
origin = lower, extent = extension)
h1.set_cmap("gist_heat")
plt.tight_layout()

El campo total se genera llamando a las dos funciones secuencialmente, transmitiendo el valor u2 de una a la otra
funcin:
u2=mascara_cuadrado()
difraccion_varias_posiciones(u2, distancias = sp.linspace(25 * um, 2* mm, 5))
plt.show()

mascara z=25 m z=34 m z=43 m z=53 m


10
5
0
5
10
10 5 0 5 10

z=62 m z=71 m z=81 m z=90 m z=100 m

Eventualmente, si la distancia de propagacin fuera mucho mayor que la distancia de Fresnel, >> 2 /, el
campo difractado sera la transformada de Fourier del objeto (pues estamos iluminando con onda plana), en este
caso una funcin sinc.

13.5 Difraccin por una abertura circular

Una mscara de gran importancia en la ptica es la abertura circular. Segn hemos definido la clase mascarasXY,
para determinar el campo generado por la mscara circular, los ejemplos anteriores son completamente vlidos, y
solamente es necesaio intercambiar la funcin de creacin de la mscara
t1.circulo(r0 = (0 * um, 0 * um), radius = (radio, radio))

Se muestran los resultados, pero no el cdigo que es casi idntico

196 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

circulo z=1282 m
40 40

20 20

0 0

20 20

40 40
40 20 0 20 40 40 20 0 20 40

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

1.5
Intensidad

1.0

0.5

40 20 0 20 40
h (perfil)
Para este ejemplo se ha elegido que la distancia sea exactamente la mitad de la distancia de Fresnel
t1.circulo(r0 = (0 * um, 0 * um), radius = (radio, radio))
#distancia de fresnel
z_fresnel = radio ** 2 / lambda0

#plano de observacion

13.5. Difraccin por una abertura circular 197


PIMCD2013-python, Publicacin 1.0

z_difraccion = .5 * z_fresnel

puesto que a esta distancia aparece un anillo bien definido.


En el archivo difraccion_circulo_varias_distancias.py se muestra la difraccin en campo cer-
cano a varias distancias. Ntese que en la funcin difraccion_varias_posiciones las variables filas y
columnas permiten reordenar las figuras (hasta 16) segn su nmero.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

import sys
sys.path.append(../)
sys.path.append(../general/)

from camposXY import * #@UnusedWildImport


from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccion_varias_posiciones(u2, distancias):

plt.figure(figsize=(12,8))

num_figuras = len(distancias)

filas = [1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 4, 4, 4, 4, 5, 4]
columnas = [1, 2, 3, 2, 3, 3, 3, 3, 3, 5, 3, 3, 4, 4, 3, 4]

extension=[u2.x[0],u2.x[-1],u2.y[0],u2.y[-1]]
plt.subplot(filas[num_figuras], columnas[num_figuras], 1)
h1 = plt.imshow(abs(u2.u) ** 2, interpolation = bilinear,
origin = lower, extent = extension)
h1.set_cmap("gist_heat")

plt.title(ucircle)

for z, i in zip(distancias, range(num_figuras)):


#difraccion a la distancia estipulada
u3 = u2.RS(z = z, newField = True)
texto = "z=%d $\mu m$" % (z)
#carga de los dibujos
plt.subplot(filas[num_figuras], columnas[num_figuras], i + 2)
plt.axis(off)
plt.title(texto)
h1 = plt.imshow(abs(u3.u) ** 2, interpolation = bilinear,
origin = lower, extent = extension)
h1.set_cmap("gist_heat")
plt.tight_layout()

def mascara_circulo():
tamano = 100 * um
ndatos = 256

198 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)


y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
lambda0 = 0.6238 * um

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);


u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t1.circulo(r0 = (0 * um, 0 * um), radius = (40*um, 40*um))

num_figuras = 3
z_fresnel = (tamano) ** 2 / lambda0
distancias_difraccion = sp.linspace(25 * um, .25 * z_fresnel, num_figuras)

u2 = u1 * t1
return u2

u2=mascara_circulo()
difraccion_varias_posiciones(u2, distancias = sp.linspace(25 * um, 1* mm, 3))
plt.show()

13.6 Difraccin por un borde

En este epgrafe se considera como elemento difractor un borde. As se considera como mscara una mscara
binaria, y se calcula la propagacina una distancia de 25 um de la mscara. El proceder es anlogo a una mscara
cuadrada.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

import sys
sys.path.append(../)

from camposXY import * #@UnusedWildImport


from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccion_borde():
#tamano de area de visualizacion
tamano = 100 * um
ndatos = 256
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
#longitud de onda
lambda0 = 0.6238 * um

#fuente de iluminacion
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

#mascara

13.6. Difraccin por un borde 199


PIMCD2013-python, Publicacin 1.0

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t1.dosNiveles(nivel1 = 0, nivel2 = 1, xcorte = 0 * um)
u2 = u1 * t1

#plano de observacion
z_difraccion = 25*um

u3 = u2.RS(z = z_difraccion, newField = True)


texto = "z=%d $\mu m$" % (z_difraccion)
dibujar_varios_campos(campos=(u2,u3),titulos=(circulo, texto))
u3.dibujar_perfil(punto1=(-15, 0),punto2=(15,0), tipo=intensidad)
h,perfil,p1,p2=t1.perfil(punto1=(-15, 0),punto2=(15,0), tipo=intensidad,order=0)
plt.hold(True)
plt.plot(h,perfil,r,lw=2)

difraccion_borde()
plt.show()

circulo z=25 m
40 40

20 20

0 0

20 20

40 40
40 20 0 20 40 40 20 0 20 40

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

200 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

1.4

1.2

1.0
Intensidad

0.8

0.6

0.4

0.2

15 10 5 0 5 10
h (perfil)
Debido a la difraccin, la luz al propagarse se introduce en la sombra, como se observa en el perfil.
Veamos que ocurre a varias distancias. A medida que nos separamos del borde, ms luz entra en la zona de sombra
y mas perceptibles son los efectos difractivos
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

import sys
sys.path.append(../)
sys.path.append(../general/)

from camposXY import * #@UnusedWildImport


from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccion_varias_posiciones(u2, distancias):

plt.figure(figsize=(12,6))

num_figuras = len(distancias)

filas = [1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 4, 4, 4, 4, 5, 4]

13.6. Difraccin por un borde 201


PIMCD2013-python, Publicacin 1.0

columnas = [1, 2, 3, 2, 3, 3, 3, 3, 3, 5, 3, 3, 4, 4, 3, 4]

plt.subplot(filas[num_figuras], columnas[num_figuras], 1)
h1 = plt.imshow(abs(u2.u) ** 2)
h1.set_cmap("gist_heat")

plt.title(umascara)

for z, i in zip(distancias, range(num_figuras)):


#difraccion a la distancia estipulada
u3 = u2.RS(z = z, newField = True)
texto = "z=%d $\mu m$" % (z)
#carga de los dibujos
plt.subplot(filas[num_figuras], columnas[num_figuras], i + 2)
plt.axis(off)
plt.title(texto)
h1 = plt.imshow(abs(u3.u) ** 2)
h1.set_cmap("gist_heat")

def mascara_borde():
tamano = 100 * um
ndatos = 256
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
lambda0 = 0.6238 * um

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);


u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t1.dosNiveles(nivel1 = 0, nivel2 = 1, xcorte = 0 * um)

num_figuras = 8
z_fresnel = (tamano) ** 2 / lambda0
distancias_difraccion = sp.linspace(25 * um, .25 * z_fresnel, num_figuras)

u2 = u1 * t1
return u2

u2=mascara_borde()
difraccion_varias_posiciones(u2, distancias = sp.linspace(10 * um, 100* um, 2))
plt.tight_layout()
plt.show()

13.7 Difraccin por una doble rendija

En este caso el elemento difractor es una doble rendija. Se calcula la propagacin a varias disntancias talesque la
distribucin de intensidad no est en la posicin de la zona clara, sino en la zona opaca, en contradiccin con la
teora geomtrica (cosas que tienen los efectos difractivos), es decir entre las dos rendijas.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL

202 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

# Objetivo: difraccion por doble rendija


#-------------------------------------

import sys
sys.path.append(../)
sys.path.append(../general/)

from camposXY import * #@UnusedWildImport


from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccionDobleRendija():
tamano = 250 * um
numdatos = 128
x0 = sp.linspace(-tamano / 2 , tamano / 2, numdatos)
y0 = sp.linspace(-tamano / 2 , tamano / 2, numdatos)
lambda0 = 0.6238 * um
z = 4 * mm

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);


u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

t = mascaraXY(x = x0, y = y0, wavelength = lambda0);


t.dobleRendija(x0 = 0 * um, size = 25 * um, separacion = 50 * um, angulo = 0 * grados)

u2 = u1 * t
u3 = u2.RS(z=z, newField = True)

texto = "z=%d $\mu m$" % (z)


dibujar_varios_campos(campos=(u2,u3),titulos=(doble rendija, texto))

difraccionDobleRendija()
plt.show()

doble rendija z=4000 m


100 100

50 50

0 0

50 50

100 100
100 50 0 50 100 100 50 0 50 100

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Ntese como aunque la ptica geomtrica predice la no existencia de luz en dicha regin, experimentalmente (en
este caso simulacin) se observa un patrn de intensidad en dicha regin. Este muestra como la difraccin es la
capacidad de la luz para sortear bordes y agujeros.

13.7. Difraccin por una doble rendija 203


PIMCD2013-python, Publicacin 1.0

13.8 Difraccin por una lente

Otro ejemplo es la difraccin por una lente, de la cual mostramos la intensidad y la fase. Debido a que la lente
se ha suspuesto rotacionalmente simtrica, el patrn de difraccin es perfectamente simtrico. As se muestra un
perfil de intensidad.
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

import sys
sys.path.append(../)
sys.path.append(../general/)

from camposXY import * #@UnusedWildImport


from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccion_lente():
tamano = 200 * um
numdatos = 256
x0 = sp.linspace(-tamano / 2 , tamano / 2, numdatos)
y0 = sp.linspace(-tamano / 2 , tamano / 2, numdatos)
lambda0 = 0.6238 * um

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);


u1.onda_plana();

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0);


t1.circulo(r0 = (0 * um, 0 * um), radius = (90 * um, 90 * um), angulo = 45 * grados)

t2 = mascaraXY(x = x0, y = y0, wavelength = lambda0);


t2.lente(r0 = (0 * um, 0 * um), radius = (90 * um, 90 * um), focal = (2 * mm, 2 * mm), ang

t = t1 * t2
t.dibujar(tipo = campo)

u3 = u1 * t
u3 = u3.RS(z = 2 * mm, newField = True)
u3.dibujar(tipo = intensidad)

u3.dibujar_perfil(punto1=(-30*um, 0),punto2=(30*um,0), tipo=intensidad)

difraccion_lente()
plt.show()

204 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

100
amplitud 100
fase

50 50
y(m)

y(m)
0 0

50 50

100100 50 0 50 100 100100 50 0 50 100


x(m) x(m)
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 2.4 1.6 0.8 0.0 0.8 1.6 2.4

100 400

350
50 300

250
y(m)

0 200

150

50 100

50

100100 50 0 50 100 0
x(m)

13.8. Difraccin por una lente 205


PIMCD2013-python, Publicacin 1.0

400

300
Intensidad

200

100

0 30 20 10 0 10 20
h (perfil)
13.9 Difraccin por una lente binaria

En este ltimo ejemplo se supone una lente de Fresnel. Este tipo de lentes es puramente difractiva. As se obtiene
#!/usr/local/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------

import sys
sys.path.append(../)
from camposXY import * #@UnusedWildImport
from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

def difraccion_lente_binaria():
tamano = 200 * um
numdatos = 256
x0 = sp.linspace(-tamano / 2 , tamano / 2, numdatos)
y0 = sp.linspace(-tamano / 2 , tamano / 2, numdatos)
lambda0 = 0.6238 * um

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);


u1.onda_plana();

206 Captulo 13. Difraccin en campo cercano


PIMCD2013-python, Publicacin 1.0

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0);


t1.circulo(r0 = (0 * um, 0 * um), radius = (90 * um, 90 * um), angulo = 45 * grados)

t2 = mascaraXY(x = x0, y = y0, wavelength = lambda0);


t2.lente(r0 = (0 * um, 0 * um), radius = (90 * um, 90 * um), focal = (2 * mm, 2 * mm), ang
t2.discretizar(tipo = fase, numNiveles = 2, factor = 1, campoNuevo = False, matriz = Fal

t = t1 * t2
t.dibujar(tipo = campo)
u3 = u1 * t
u3 = u3.RS(z = 2 * mm, newField = True)
u3.dibujar(tipo = intensidad)
u3.dibujar_perfil(punto1=(-30*um, 0),punto2=(30*um,0), tipo=intensidad)

difraccion_lente_binaria()
plt.show()

100
amplitud 100
fase

50 50
y(m)

y(m)

0 0

50 50

100100 50 0 50 100 100100 50 0 50 100


x(m) x(m)
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.4 0.8 1.2 1.6 2.0 2.4 2.8

13.9. Difraccin por una lente binaria 207


PIMCD2013-python, Publicacin 1.0

100
160

140
50
120

100
y(m)

0 80

60
50 40

20

100100 50 0 50 100 0
x(m)

150
Intensidad

100

50

0 30 20 10 0 10 20
h (perfil)

208 Captulo 13. Difraccin en campo cercano


CAPTULO 14

Difraccin en campo lejano

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto

Contenidos de este captulo:


Introduccin
Difraccin por un cuadrado
Difraccin por una rendija
Difraccin por un crculo
Difraccin por una doble rendija
Difraccin por una estructura complicada: estrella
Difraccin por una estructura complicada: fotografa
Difraccin por una red de sinusoidal
Difraccin por una red de Ronchi
Propiedades de la transformada de Fourier
Desplazamiento del objeto
Rotacin del objeto
Haz con distinto ngulo de entrada
Misma mscara, distinto haz
Mscara con distinto tamao
Distinta longitud de onda

Herramientas utilizadas en este tutorial:


numpy: manipulacin de datos
scipy: Herramientas matemticas
Archivos necesarios para esta seccin:
camposXY.py. Archivo con las funciones principales camposXY.py
fuentesXY.py. Archivo con las funciones principales fuentesXY.py
mascarasXY.py. Archivo con las funciones principales mascarasXY.py
Descarga de archivos:
Ejemplo de difraccin por un cuadrado difraccion_cuadrado.py
Ejemplo de difraccin por un rectngulo difraccion_rectangulo.py
Ejemplo de difraccin por una rendija difraccion_rendija.py
Ejemplo de difraccin por un circulo difraccion_circulo.py
Ejemplo de difraccin por una doble rendija difraccion_doble_rendija.py
Ejemplo de difraccin por una estrella difraccion_estrella.py

209
PIMCD2013-python, Publicacin 1.0

Ejemplo de difraccin por una estructura compleja difraccion_lena.py


Ejemplo de difraccin por una red sinusoidal difraccion_red_seno.py
Ejemplo de difraccin por una red de Ronchi difraccion_red_ronchi.py
Ejemplo de desplazamiento difraccion_desplazamiento.py
Ejemplo de difraccin con rotacin difraccion_rotacion.py
Ejemplo de difraccin con un haz inclinado difraccion_haz_inclinado.py
Ejemplo de difraccin con dos haces diferentes difraccion_distinto_haz.py
Ejemplo de difraccin al cambiar el tamao difraccion_tamano.py
Ejemplo de difraccin con distinta longitud de onda difraccion_longitud_onda.py

14.1 Introduccin

En esta seccin analizaremos la difraccin en campo lejano bajo la aproximacin de Fraunhofer.


El efecto de las interferencias surgen directamente de que las ecuaciones de Maxwell son lineales en los campos
elctricos y magnticos. Supongamos que E1 y E2 son soluciones. Entonces

2


donde a es el tamao mximo del elemento difractor. Bajo esta aproximacin, el campo difractado se puede
calcular como una integral
2 + 2
(+ 2 )

E(, , ) = E0 (, ) (+) .

donde E0 (, ) es el campo justo a la salida del elemento difractor.


La aproximacin ms usual para este campo es considerar que se obtiene como el producto del campo incidente
E (, ) por el coeficiente de transmisin del mscara (, )E (, )

E (, ) = (, )E (, ).

La gran ventaja de esta ecuacin es que se puede escribir como una transformada de Fourier, que es una operacin
bastante conocida en matemticas
2 + 2
(+ 2 )
E(, , ) = [E0 (, )] .

Como el primer trmino delante de la transformada de Fourier es casi constante para un plano z determinado, se
suele eliminar.

14.2 Difraccin por un cuadrado

Vamos a calcular mediante implementacin de cdigo de Python el campo difractado a partir de una mscara
cuadrada. Se observa el perfil con la tpica figura de 2 ()
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano

210 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

#-------------------------------------

#Anadimos las direcciones de las clases que se utilizan


import sys
sys.path.append(../)
#Se cargan las clases que se utilizan
from fuentesXY import *
from mascarasXY import mascaraXY, dibujar_varios_campos

#Datos de tamanos predeterminados


tamano = 250 * um
npuntos = 1024
x0 = sp.linspace(-tamano * um, tamano * um, npuntos)
y0 = sp.linspace(-tamano * um, tamano * um, npuntos)

#Longitud de onda predeterminada


lambda0 = 0.6238 * um

def difraccion_cuadrado():
#Se carga la clase fuentes
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
#Condicion de onda plana
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
#Trabajaremos con la clase mascaras
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
#Mascara cuadrada
t1.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)
#Campo por mascara
u2 = u1 * t1
#Transformada de Fourier
u3 = u2.fft(quitar0 = False)
#Representacion
dibujar_varios_campos(campos=(t1,u3), titulos=(mascara,campo lejano), logaritmico=True
plt.axis([u3.x.min()/3, u3.x.max()/3, u3.y.min()/3, u3.y.max()/3])
punto1=(u3.x.min(),0)
punto2=(u3.x.max(), 0)
u3.dibujar_perfil(punto1,punto2, normalizar=maximo)

difraccion_cuadrado()
plt.show()

mascara campo lejano


2000
200

1000
100

0 0

100
1000

200
2000
200 100 0 100 200 2000 1000 0 1000 2000

14.2. Difraccin por un cuadrado 211


PIMCD2013-python, Publicacin 1.0

1.0

0.8
Intensidad

0.6

0.4

0.2

0.0 6000 4000 2000 0 2000 4000 6000


h (perfil)
Tras haber ejecutado el cdigo se obtiene la mscara y el patrn de intensidades, as mismo se muestra un perfil
de intensidad.

14.3 Difraccin por una rendija

En este ejemplo calcular el campo difractado Por una rendija. Es muy parecido al cuadrado, pero en una de las
direcciones colapsa a una lnea, pues la transformada de Fourier de un campo plano (en la direccin y) es una delta
de Dirac.
def difraccion_rendija():
#Clase fuentes
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
#Iluminacion de onda plana
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
#Clase mascaras
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
#Rendija
t1.rendija(x0 = 0, size = 5 * um, angulo = 0 * grados)
#Campo transmitido
u2 = u1 * t1
#Campo difractado
u3 = u2.fft(quitar0 = False)
#Representacion
dibujar_varios_campos(campos=(u2, u3),titulos=(mascara, fft),
titulo=tamano, logaritmico = True, normalizar = maximo )
plt.set_cmap("gray")
#perfiles
punto1=(u3.x.min()/2,0)
punto2=(u3.x.max()/2,0)

212 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

h, z_perfil, punto1, punto2=u3.dibujar_perfil(punto1,punto2, npixels=npuntos, \


normalizar = maximo)

Tras ejecutar el cdigo se obtiene la mscara y el patrn de intensidades, as mismo se muestra un perfil de
intensidad.

mascara tamano fft


100 10000

50 5000

0 0

50 5000

100 10000
100 50 0 50 100 10000 5000 0 5000 10000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

1.0

0.8
Intensidad

0.6

0.4

0.2

6000 4000 2000 0 2000 4000 6000


h (perfil)

14.3. Difraccin por una rendija 213


PIMCD2013-python, Publicacin 1.0

14.4 Difraccin por un crculo

Se calcula el campo difractado por una mscara circular. El resultado muestra el perfil con la tpica figura de
02 ().
def difraccion_circulo():
#Clase fuentes
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
#Iluminacion onda plana
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
#Clase mascaras
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
#Mascara
t1.circulo(r0 = (0 * um, 0 * um), radius = (15 * um, 15 * um), angulo = 0 * grados)
#Campo transmitido
u2 = u1 * t1
#Campo difractado
u3 = u2.fft(quitar0 = False)
#Representacion
punto1=(u3.x.min()/5,0)
punto2=(u3.x.max()/5,0)
dibujar_varios_campos(campos=(t1,u3), titulos=(mascara,campo lejano), logaritmico=True
plt.axis([u3.x.min()/3, u3.x.max()/3, u3.y.min()/3, u3.y.max()/3])
u3.dibujar_perfil(punto1,punto2, normalizar=maximo)

Tras ejecutar el cdigo se obtiene la mscara y el patrn de intensidades, as mismo se muestra un perfil de
intensidad.

mascara 2000
campo lejano
200

100 1000

0 0

100 1000

200
2000
200 100 0 100 200 2000 1000 0 1000 2000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

214 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

0.8
Intensidad

0.6

0.4

0.2

0.0 1000 500 0 500 1000


h (perfil)
14.5 Difraccin por una doble rendija

Se muestra tambin la figura de difraccin de una nica rendija y se observa que es la envolvente de la doble
rendija: doble rendija = difraccin de una rendija + interferencia entre dos rendijas.
def difraccion_doble_rendija():
#Clase fuentes
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
#Iluminacion onda plana
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
#Doble rendija
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.dobleRendija(x0 = 0, size = 5 * um, separacion = 20 * um, angulo = 0 * grados)
#Campo transmitido y difractado 1
u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

#Rendija (para ver que es la convolucion de la doble rendija)


t3 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t3.rendija(x0 = 0, size = 5 * um, angulo = 0 * grados)
#Campo transmitido y difractado 2
u4 = u1* t3
u5 = u4.fft(quitar0 = False)

#Dibujar mascara y transformada


dibujar_varios_campos(campos=(u2,u3), titulos=(mascara,fft), \
logaritmico=True, normalizar=maximo)
#Perfiles
punto1=(u5.x.min(),0)

14.5. Difraccin por una doble rendija 215


PIMCD2013-python, Publicacin 1.0

punto2=(u5.x.max(),0)
h, z_perfil, punto1, punto2=u5.perfil(punto1,punto2)
u3.dibujar_perfil(punto1,punto2, normalizar = maximo)
plt.plot(h,z_perfil/z_perfil.max(),r,lw=2)
plt.legend((doble rendija, una rendija))
plt.xlim(h.min()/3,h.max()/3)

Tras ejecutar el cdigo se obtiene la mscara y el patrn de intensidades, as mismo se muestra un perfil de
intensidad. Ntese como la envolvente del patrn de intensidades en la pantalla es la intensidad de una nica
rendija.

100 mascara 15000


fft
10000
50
5000
0 0
5000
50
10000

100100 15000
50 0 50 100 1500010000 5000 0 5000 1000015000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

216 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

doble rendija
una rendija
0.8
Intensidad

0.6

0.4

0.2

0.0 4000 2000 0 2000 4000


h (perfil)
14.6 Difraccin por una estructura complicada: estrella

Las estructuras ms complejas tienen una distribucin en el plano de Fourier tambin ms complejo. En este
ejemplo la mscara ha sido una estrella, esta se ha cargado a partir de una imagen binarizada, por tanto no ha sido
programada o tomada de la clase mscaraXY.
def difraccion_estrella():
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.imagen(nombre=estrella_pequena.png)

u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

dibujar_varios_campos(campos=(u2,u3), titulos=(mascara,fft), \
logaritmico=True, normalizar=maximo)

Tras ejecutar el cdigo se obtiene la mscara y el patrn de intensidades.

14.6. Difraccin por una estructura complicada: estrella 217


PIMCD2013-python, Publicacin 1.0

mascara 3000
fft
200
2000
100
1000
0 0
1000
100
2000
200
3000
200 100 0 100 200 3000 2000 1000 0 1000 2000 3000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.7 Difraccin por una estructura complicada: fotografa

Las estructuras ms complejas tienen una distribucin en el plano de Fourier tambin ms complejo, este es el
caso de una fotografa real, en la cual debido a los mltiples detalles, la transformada de Fourier se muestra como
un patrn del que podra decirse que carece de orden, sin embargo conserva la informacin de la imagen original.
def difraccion_lena():
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.imagen(nombre=lena.png)

u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

dibujar_varios_campos(campos=(u2,u3), titulos=(mascara,fft), \
logaritmico=True, normalizar=maximo)

Tras ejecutar el cdigo se obtiene la mscara y el patrn de intensidades.

218 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

mascara 3000
fft
200
2000
100
1000
0 0
1000
100
2000
200
3000
200 100 0 100 200 3000 2000 1000 0 1000 2000 3000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.8 Difraccin por una red de sinusoidal

La red sinusoidal tiene solamente tres frecuencias espaciales, que son las que se observan en la figura de difraccin.
def difraccion_red_seno():
#tamano de area de visualizacion
tamano = 1000 * um
ndatos = 512
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
#longitud de onda
lambda0 = 0.6238 * um

#fuente de iluminacion
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

#mascara
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.red_seno(periodo=40*um)
u2 = u1 * t1

u3 = u2.fft(quitar0 = False)

u2.dibujar()

punto1=(u3.x.min(),0)
punto2=(u3.x.max(),0)

u3.dibujar_perfil(punto1,punto2, normalizar=maximo, order=2)

Tras ejecutar el cdigo se obtiene la mscara y el perfil de intensidades en la pantalla.

14.8. Difraccin por una red de sinusoidal 219


PIMCD2013-python, Publicacin 1.0

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)

0.8

0.6
Intensidad

0.4

0.2

0.0

1500 1000 500 0 500 1000 1500


h (perfil)

220 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

14.9 Difraccin por una red de Ronchi

La red de Ronchi tiene ms frecuencias espaciales, todas equidistanciadas, que son las que se observan en la figura
2
de difraccin. La altura de cada pico es el cuadrado del valor del coeficiente de Fourier , = | | .
def difraccion_red_ronchi():
#tamano de area de visualizacio
tamano = 1000 * um
ndatos = 512
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
#longitud de onda
lambda0 = 0.6238 * um

#fuente de iluminacion
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

#mascara
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.red_ronchi( periodo = 40 * um, x0 = 0 * um, fillFactor = 0.5, angulo = 0 * grados)
u2 = u1 * t1

u3 = u2.fft(quitar0 = False)

u2.dibujar()

punto1=(u3.x.min(),0)
punto2=(u3.x.max(),0)

u3.dibujar_perfil(punto1,punto2, normalizar=maximo, order=2)

Tras ejecutar el cdigo se obtiene la mscara y el perfil de intensidades en la pantalla.

14.9. Difraccin por una red de Ronchi 221


PIMCD2013-python, Publicacin 1.0

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)

0.8

0.6
Intensidad

0.4

0.2

0.0

1500 1000 500 0 500 1000 1500


h (perfil)

222 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

14.10 Propiedades de la transformada de Fourier

En esta seccin se analizan las propiedades matemticas de la transformada de Fourier, a traves de la observacin
de la misma en el plano de Fourier.

14.10.1 Desplazamiento del objeto

En este epgrafe mostramos como desplazar un elemento difractivo, la distribucin de intensidad es la misma (no
la fase). Esto matemticamente se corresponde con la propiedad:

[ ( )]() = [ ()]()

As queda patente al ejecutar el siguiente cdigo, el cual considera la difraccin por una mscara cuadrada. Las
figuras muestras la mscara y su desplazamiento as como la obsercacin en el plano de Fourier de sendas msca-
ras.
def difraccion_desplazamiento():
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)

t2 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t2.cuadrado(r0 = (100 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)

u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

u4 = u1 * t2
u5 = u4.fft(quitar0=False)

dibujar_varios_campos(campos=(t1,t2), titulos=(x=0 um,x=100*um), titulo=desplazamient


logaritmico=True, normalizar=maximo)

dibujar_varios_campos(campos=(u3,u5), titulos=(x=0 um,x=100*um), \


titulo=desplazamiento, logaritmico=True, normalizar=max

x=0 um desplazamiento x=100*um


200 200

100 100

0 0

100 100

200 200
200 100 0 100 200 200 100 0 100 200

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.10. Propiedades de la transformada de Fourier 223


PIMCD2013-python, Publicacin 1.0

6000
x=0 um desplazamiento
6000
x=100*um
4000 4000
2000 2000
0 0
2000 2000
4000 4000
6000 6000
6000 4000 2000 0 2000 4000 6000 6000 4000 2000 0 2000 4000 6000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.10.2 Rotacin del objeto

En este epgrafe se considera el mismo elemento difractivo del ejemplo anterior pero aplicndole una rotacin, as
resulta una rotacin de la transformada de Fourier.
def difraccion_rotacion():
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)

t2 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t2.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 45 * grados)

u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

u4 = u1 * t2
u5 = u4.fft(quitar0=False)

dibujar_varios_campos(campos=(t1,t2), titulos=(0 grados,45 grados), \


titulo=desplazamiento, logaritmico=True,\
normalizar=maximo)

dibujar_varios_campos(campos=(u3,u5), titulos=(0 grados,45 grados), \


titulo=rotacion, logaritmico=True,\
normalizar=maximo)

224 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

0 grados desplazamiento 45 grados


200 200

100 100

0 0

100 100

200 200
200 100 0 100 200 200 100 0 100 200

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

0 grados rotacion 45 grados


6000 6000
4000 4000
2000 2000
0 0
2000 2000
4000 4000
6000 6000
6000 4000 2000 0 2000 4000 6000 6000 4000 2000 0 2000 4000 6000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.10.3 Haz con distinto ngulo de entrada

Si el ngulo del incidencia es variado, la posicin en el plano de Fourier del orden cero de difraccin se ve
desplazada.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

#anadimos las direcciones de las clases que se utilizan


import sys

14.10. Propiedades de la transformada de Fourier 225


PIMCD2013-python, Publicacin 1.0

sys.path.append(../)

#se cargan las clases que se utilizan


from fuentesXY import *
from mascarasXY import mascaraXY, dibujar_varios_campos

#datos de tamanos predeterminados


tamano = 250 * um
npuntos = 1024
x0 = sp.linspace(-tamano * um, tamano * um, npuntos)
y0 = sp.linspace(-tamano * um, tamano * um, npuntos)

#longitud de onda predeterminada


lambda0 = 0.6238 * um

def difraccion_haz_inclinado(haz_incidente):
u1=haz_incidente
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)
u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

return u2, u3

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)


u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1, fft1= difraccion_haz_inclinado(u1)

u2 = fuenteXY(x = x0, y = y0, wavelength = lambda0)


u2.onda_plana(A = 1, theta = sp.pi / 2, phi = 15 * grados)
t2, fft2= difraccion_haz_inclinado(u2)

dibujar_varios_campos(campos=(fft1,fft2), titulos=(0 grados,15 grados), \


titulo=fft, logaritmico=True, normalizar=maximo)

plt.show()

0 grados fft 15 grados


6000 6000
4000 4000
2000 2000
0 0
2000 2000
4000 4000
6000 6000
6000 4000 2000 0 2000 4000 6000 6000 4000 2000 0 2000 4000 6000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

226 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

14.10.4 Misma mscara, distinto haz

Se compara la difraccin por un mscara cuadrada bajo dos fuentes de iluminacin, un haz de entrada en primer
lugar considerado una onda plana y en segudno, una onda gaussiana con un tamao comparable al elemento
difractor. El resultado, muestra como en el caso del haz gausiano, la mayor parte de la energa del haz difractado
se concentra en los rdenes ms bajo de difraccin. Mientras que en el caso de una onda plana, la energa est ms
repartida entre los distintos rdenes.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-

#----------------------------------------------------------------------
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Breaje
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

#anadimos las direcciones de las clases que se utilizan


import sys
sys.path.append(../)

#se cargan las clases que se utilizan


from fuentesXY import *
from mascarasXY import mascaraXY, dibujar_varios_campos

#datos de tamanos predeterminados


tamano = 250 * um
npuntos = 1024
x0 = sp.linspace(-tamano * um, tamano * um, npuntos)
y0 = sp.linspace(-tamano * um, tamano * um, npuntos)

#longitud de onda predeterminada


lambda0 = 0.6238 * um

def difraccion_rectangulo_onda_plana(haz_incidente):

u1=haz_incidente

t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)


t1.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)

u2 = u1 * t1
u2.dibujar(tipo = intensidad, logaritmico = False, normalizar = maximo)
plt.axis([-15*um,15*um,-15*um,15*um])

u3 = u2.fft(quitar0 = False)

return u2, u3

u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)


u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1, fft1= difraccion_rectangulo_onda_plana(u1)

u2 = fuenteXY(x = x0, y = y0, wavelength = lambda0)


u2.haz_gauss(A = 1, r0 = (0 * um, 0 * um), w = (5 * um, 5 * um), \
theta = 0.*grados, phi = 0 * grados)
t2, fft2= difraccion_rectangulo_onda_plana(u2)

14.10. Propiedades de la transformada de Fourier 227


PIMCD2013-python, Publicacin 1.0

dibujar_varios_campos(campos=(fft1,fft2), titulos=(plana,gauss), titulo=fft, logaritmico=Tru

plt.show()

15 1.0
0.9
10
0.8
0.7
5
0.6
y(m)

0 0.5
0.4
5
0.3
0.2
10
0.1
1515 10 5 0 5 10 15 0.0
x(m)

228 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

15 1.0
0.9
10
0.8
0.7
5
0.6
y(m)

0 0.5
0.4
5
0.3
0.2
10
0.1
1515 10 5 0 5 10 15 0.0
x(m)
plana fft gauss
6000 6000
4000 4000
2000 2000
0 0
2000 2000
4000 4000
6000 6000
6000 4000 2000 0 2000 4000 6000 6000 4000 2000 0 2000 4000 6000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.10.5 Mscara con distinto tamao

Considrense dos mscaras con la misma topologa pero de distinto tamao. La observacin del haz difractado en
el plano de Fourier cambia de escala, esto es mantiene la misma topologa pero no su tamao.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------

14.10. Propiedades de la transformada de Fourier 229


PIMCD2013-python, Publicacin 1.0

# Autor: Luis Miguel Sanchez Breaje


# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

#anadimos las direcciones de las clases que se utilizan


import sys
sys.path.append(../)

#se cargan las clases que se utilizan


from fuentesXY import *
from mascarasXY import mascaraXY, dibujar_varios_campos

#datos de tamanos predeterminados


tamano = 250 * um
npuntos = 1024
x0 = sp.linspace(-tamano * um, tamano * um, npuntos)
y0 = sp.linspace(-tamano * um, tamano * um, npuntos)

#longitud de onda predeterminada


lambda0 = 0.6238 * um

def difraccion_tamano(anchura):
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0)
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.cuadrado(r0 = (0 * um, 0 * um), size = (anchura,anchura), angulo = 0 * grados)

u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

return t1, u3

fft_pequeno, t1=difraccion_tamano(5*um)
fft_grande, t2 =difraccion_tamano(15*um)

dibujar_varios_campos(campos=(t1,t2), titulos=(r$5\,\mu m$, r$15\,\mu m$), \


titulo=desplazamiento, logaritmico=True, normalizar=maximo)

dibujar_varios_campos(campos=(fft_pequeno,fft_grande),titulos=(r$5\,\mu m$, r$15\,\mu m$),


titulo=tamano, logaritmico = True, normalizar = maximo )

plt.show()

230 Captulo 14. Difraccin en campo lejano


PIMCD2013-python, Publicacin 1.0

5 m desplazamiento 15 m
6000 6000
4000 4000
2000 2000
0 0
2000 2000
4000 4000
6000 6000
6000 4000 2000 0 2000 4000 6000 6000 4000 2000 0 2000 4000 6000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

5 m tamano 15 m
200 200

100 100

0 0

100 100

200 200
200 100 0 100 200 200 100 0 100 200

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

14.10.6 Distinta longitud de onda

Si se considera una misma mscara pero distintas longitudes de onda de luz incidente en el plano de Fourier se
observa que la distribucin de intensidad es la misma, pero no su tamao. Este hecho queda patente en las figuras
ejemplo fruto de ejecutar el cdigo de abajo. Si tuvieran distinta escala se veran diferente.
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Breaje
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
# Objetivo: Ejemplos de difraccion en campo lejano
#-------------------------------------

#anadimos las direcciones de las clases que se utilizan

14.10. Propiedades de la transformada de Fourier 231


PIMCD2013-python, Publicacin 1.0

import sys
sys.path.append(../)

#se cargan las clases que se utilizan


from fuentesXY import *
from mascarasXY import mascaraXY, dibujar_varios_campos

#datos de tamanos predeterminados


tamano = 250 * um
npuntos = 1024
x0 = sp.linspace(-tamano * um, tamano * um, npuntos)
y0 = sp.linspace(-tamano * um, tamano * um, npuntos)

def difraccion_cuadrado(longitud_onda):
u1 = fuenteXY(x = x0, y = y0, wavelength = longitud_onda)
u1.onda_plana(A = 1, theta = sp.pi / 2, phi = 0 * grados)
t1 = mascaraXY(x = x0, y = y0, wavelength = longitud_onda)
t1.cuadrado(r0 = (0 * um, 0 * um), size = (15 * um, 15 * um), angulo = 0 * grados)

u2 = u1 * t1
u3 = u2.fft(quitar0 = False)

return u3

s1=difraccion_cuadrado(0.405*um)
s2=difraccion_cuadrado(0.6328*um)
dibujar_varios_campos(campos=(s1,s2), titulos=(r$0.405\,\mu m$, r$0.6238\,\mu m$), \
logaritmico=True, normalizar=maximo)

plt.show()

4000
0.405 m 0.6238 m
6000
3000
4000
2000
1000 2000
0 0
1000 2000
2000
4000
3000
4000 6000
4000300020001000 0 1000200030004000 6000 4000 2000 0 2000 4000 6000

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

232 Captulo 14. Difraccin en campo lejano


CAPTULO 15

Redes de Difraccin

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto
Las redes de difraccin son estructuras peridicas que modulan la transmitancia de un haz incidente. Son de gran
importancia en reas como espectroscopa, para separar el espectro, o en metrologa ptica, donde se utilizan como
escalas.

Contenidos de este captulo:


Introduccin
Red Sinusoidal
Red de Ronchi
Red de Binaria
Red Blazed
Red bidimensional
Red tipo Ajedrez
Red radial
Red angular
Red con borde sinusoidal
Red hiperblica
Aplicacin como redes de difraccin en campo lejano
Difraccin por una red de sinusoidal
Difraccin por una red de Ronchi
Efecto Talbot
Efectos con dos redes

Herramientas utilizadas en este tutorial:


numpy: manipulacin de datos
scipy: Herramientas matemticas
Archivos necesarios para la definicin de redes de difraccin:
Archivo con las funciones principales mascarasXY.py
Ejemplo de una red sinusoidal ejemplo_red_seno.py
Ejemplo de una red de Ronchi ejemplo_red_ronchi.py
Ejemplo de una red blazed ejemplo_red_blazed.py
Ejemplo de una red binaria ejemplo_red_binaria.py
Ejemplo de una red tipo damero ejemplo_red_ajedrez.py
Ejemplo de una red bidimensional ejemplo_red_2D.py
Ejemplo de una red radial ejemplo_red_2D.py

233
PIMCD2013-python, Publicacin 1.0

Ejemplo de una red angular ejemplo_red_2D.py


Ejemplo de una red con borde sinusidal ejemplo_red_borde_sinusoidal.py
Ejemplo numrico del efecto Talbot efecto_talbot_numerico.py
Efecto Talbot animado efecto_talbot_animado.py
Efecto Talbot efecto_talbot.py
Efecto Talbot efecto_talbot_haz_gauss.py
Efecto Talbot para red radial efecto_talbot_red_radial.py
Efecto Vernier por variacin de ngulo efecto_vernier_angulo.py
Efecto Vernier por variacin de ngulo animado efecto_vernier_angulo_animado.py
Efecto Vernier por variacin de periodo efecto_vernier_periodo.py
Efecto Vernier por variacin de periodo animado efecto_vernier_periodo_animado.py
Desplazamiento Talbot desplazamiento_talbot_animado.py
Desplazamiento Vernier por variacin de ngulo desplazamiento_vernier_angulo_animado.py
Desplazamiento Vernier por variacin de periodo desplazamiento_vernier_periodo_animado.py
Contenidos de los archivos:
mascarasXY.py: (parte de redes)
red_seno(). Definicin de una red sinusoidal.
red_blazed(). Red tipo diente de sierra.
red_ronchi(). Implementacin de una red de Ronchi.
red_binaria(). Genera una red de franjas.
red2D(). Define una red bidimensional de franjas horizontales y verticales.
red2D_ajedrez(). Genera una red con formato tipo damero.
ejemplo_red_seno.py. Ejemplo de una red sinusoidal.
ejemplo_red_ronchi.py. Ejemplo de una red de Ronchi.
ejemplo_red_blazed.py. Ejemplo de una red Blazed.
ejemplo_red_binaria.py. Ejemplo de una red binaria.
ejemplo_red_ajedrez.py. Ejemplo de una red tipo damero.
ejemplo_red_2D.py. Ejemplo de una red bidimensional.
ejemplo_talbot_numerico.py. Ejemplo numrico del efecto Talbot.

15.1 Introduccin

Podemos definir una red de difraccin como un elemento ptico que modula de forma peridica alguna propiedad
de la luz. Normalmente existen redes de amplitud y de fase, aunque se puede modular de forma peridica cualquier
otra propiedad de la luz, tal como la polarizacin o la coherencia. Como la modulacin se produce de forma
peridica, el anlisis de cmo se comporta la red se puede realizar mediante un anlisis de Fourier, de forma que
la transmitancia se puede describir matemticamente mediante
( )
2
() = exp .

=

234 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

donde es el periodo y son los coeficientes de Fourier que se obtienen mediante


/2 ( )
1
= () exp 2 .
/2

15.2 Red Sinusoidal

Una red sinusoidal es un conjunto de franjas equiespaciadas cuya intensidad puede ser ajustada a una funcin
sinusoidal. La orientacin de las franjas puede ser arbitraria. En la funcin que nos atae su ngulo de inclinacin
aparece en el argumento como angulo. As se llama a la funcin __rotar__ dentro de la clase a fin de rotar
las franjas. Finalmente se implementa la intensidad de las franjas, entre una intensidad mnima amp_min y una
mxima amp_max. La modulacin de la intensidad ha sido definida como
[ ( )]
2( + )
() = + 1 + cos
2

donde p define el periodo de las franjas.


def red_seno(self, periodo = 40 * um, amp_min = 0, amp_max = 1, desfase = 0 * um, angulo =

#Se define la inclinacion de la red


Xrot, Yrot = self.__rotar__(angulo)

#Definicion de la sinusoidal
self.u = amp_min + (amp_max - amp_min) * (1 + sp.cos(2 * sp.pi * (Xrot + desfase)

La representacin de las franjas resulta ser


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""
ejemplos redes
"""

import sys
sys.path.append(../)
from mascarasXY import * #@UnusedWildImport

def ejemplo_redSeno():
x = sp.linspace(-250 * um, 250 * um, 512)
y = sp.linspace(-250 * um, 250 * um, 512)
wavelength = 0.6238 * um
periodo = 75 * um
t = mascaraXY(x, y, wavelength)
t.red_seno(periodo= periodo, amp_min=0, amp_max=1,\
desfase=periodo / 2, angulo=0 * grados)
t.dibujar(tipo=intensidad, titulo=red seno)

if __name__ == __main__:
ejemplo_redSeno()
plt.show()

15.2. Red Sinusoidal 235


PIMCD2013-python, Publicacin 1.0

red seno
1.0
200 0.9
0.8
100 0.7
0.6
y(m)

0 0.5
0.4
100 0.3
0.2
200 0.1

200 100 0 100 200 0.0


x(m)
Los coeficientes de Fourier para una red sinusoidal
1 1
() = 1 + cos(2 ) = 1 + 2 + 2
2 2
son

1 = 1/2, 0 = 1, 1 = 1/2.

15.3 Red de Ronchi

Una red de Ronchi es un conjunto de franjas equiespaciadas tales que los mximos y los mnimos de intensidad
poseen la misma anchura. Para la implementacin de una red de Ronchi se har uso de la clase mascaraXY
as como de la funcin rendija ya vista anteriormente en la seccin mscaras. As en primer lugar tras llamar a la
clase y generar nuestro vector salida, t con ceros a fin de optimizar nuestra funcin se calcula el nmero de franjas,
numperiodos a partir de redondear al entero ms prximo el cociente


donde p es el periodo, x nuestro vector de entrada y xmax y xmin, los mximos y mnimos de x. Finalmente
sumamos 5 con la intencin de tener un nmero de periodos suficientes y no quedarnos cortos debido al redondeo.
Con el fin de definir la anchura de la rendija se multiplica el factor de relleno por el periodo. Para definir las franjas
se llama para cada lnea a la funcin rendija, as es preciso definir un punto de inicio para la implementacin de
las franjas, xinicial siendo este el valor mnimo del vector de entrada menos el valor el puto central, x0.
Finalmente, mediante un bucle for se definen las franjas con inclinacin angulo. Esto se hace superponiendo
nuestro vector de ceros, t, cuyos valores son los mnimos con los mximos que dan lugar del uso de la funcin
rendija.

236 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

def red_ronchi(self, periodo = 40 * um, x0 = 20 * um, fillFactor = 0.5, angulo = 0 * grado


t = t2 = mascaraXY(self.x, self.y, self.wavelength);
t.u = sp.zeros(self.X.shape)

#Numero de periodos
numperiodos = int(round((self.x.max() - self.x.min()) / periodo + 5))
#Anchura de la rendija
anchuraRendija = fillFactor * periodo;

#Se define un origen


xinicial = self.x.min() - x0

#Generacion de la red
for i in range(-3, numperiodos + 1):
t2.rendija(xinicial + i * periodo, anchuraRendija, angulo)
t = t + t2

self.u = t.u

La representacin de las franjas es (solo mostramos la funcin, pues el resto es igual al ejemplo anterior)
def ejemplo_redRonchi():
x = sp.linspace(-250 * um, 250 * um, 512)
y = sp.linspace(-250 * um, 250 * um, 512)
wavelength = 0.6238 * um
periodo = 40 * um
t = mascaraXY(x, y, wavelength)
t.red_ronchi(periodo=periodo, x0=20 * um, fillFactor=0.5, angulo=0 * grados)
t.dibujar(tipo=intensidad, titulo=red Ronchi)

red Ronchi
1.0
200 0.9
0.8
100 0.7
0.6
y(m)

0 0.5
0.4
100 0.3
0.2
200 0.1

200 100 0 100 200 0.0


x(m)

15.3. Red de Ronchi 237


PIMCD2013-python, Publicacin 1.0

15.4 Red de Binaria

Una red binaria est constituida por un conjunto de franjas equiespaciadas entre s una distancia determinada, en
este caso, a travs de los parmetros de entrada podemos controlar la amplitud mnima (amin), mxima (max), el
desfase (desfase) y el factor de forma (fillFactor), adems del ngulo de rotacin (angulo)
def red_binaria(self, periodo = 40 * um, amin = 0, amax = 1, desfase = 0 * sp.pi / 2, x0 = 0, fill

def red_binaria(self, periodo = 40 * um, amin = 0, amax = 1, desfase = 0 * sp.pi / 2, x0 =


t = mascaraXY(self.x, self.y, self.wavelength);
t2 = mascaraXY(self.x, self.y, self.wavelength);
t.u = sp.zeros(self.X.shape)

#Numero de periodos
numperiodos = int(round((self.x.max() - self.x.min()) / periodo + 5))
#Anchura de la rendija
anchuraRendija = fillFactor * periodo;
#Se define un origen
xinicial = self.x.min() - x0

#Generacion de la red
for i in range(-3, numperiodos):
t2.rendija(xinicial + i * periodo + anchuraRendija, anchuraRendija, angulo
t.u = t.u + amax * t2.u * sp.exp(1.j * desfase)
t2.rendija(xinicial + i * periodo, periodo - anchuraRendija, angulo)
t.u = t.u + amin * t2.u

self.u = t.u

La representacin queda:
def ejemplo_redBinaria():
x = sp.linspace(-250 * um, 250 * um, 512)
y = sp.linspace(-250 * um, 250 * um, 512)
wavelength = 0.6238 * um
t = mascaraXY(x, y, wavelength)
t.red_binaria( periodo = 40 * um, amin=.5, amax=1, desfase=1 * sp.pi / 2,\
x0=0, fillFactor=0.5)
t.dibujar(tipo=campo, titulo=red Binaria)

amplitud red Binaria fase


200 200

100 100
y(m)

y(m)

0 0

100 100

200 200
200 100 0 100 200 200 100 0 100 200
x(m) x(m)
0.500.550.600.650.700.750.800.850.900.951.00 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4

238 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

Los coeficientes de Fourier de una red binaria (que incluye a la red de Ronchi como caso especial son

0 = 1 + 1
( )

= 1 ()
( )

2 4
donde el desfase resulta ser = ( 1) para el caso de transmisin y = ( 1) para el caso de
reflexin.

15.5 Red Blazed

Normalmente en una red de difraccin convencional la luz difractada se concentra en su mayor parte en el orden
cero. Una red Blazed es un tipo particular de red de difraccin que permite homogeneizar la luz difractada en los
distintos rdenes Esto se logra mediante una red con forma de dientes de sierra. Las redes de difraccin trabajan
bajo determinadas condiciones de iluminacin como es la longitud de onda del haz y el ngulo de incidente, que
en general se supone normal a la red. As para implementar una red Blazed se comienza definiendo el vector de
onda. La definicin de los dientes de sierra de la red se hace mediante el periodo de la red y la altura del diente, el
cociente de estas dos cantidades representa la pendiente de cada diente. La altura en cada punto de la red ser por
tanto, la pendiente de los dientes por la posicin x. La fase viene dado por el camino ptico como se muestra en k
* (indice - 1) * h la cual debe estar normalizada entre 0 y 2, esto se logra con remainder. Dado que
es relativa se fija un origen de referencia, el cual est especificado por el mnimo. Finalmente se devuelve la fase
def red_blazed(self, periodo = 40 * um, altura = 2 * um, indice = 1.5, angulo = 0 * grados
#Vector de onda
k = 2 * sp.pi / self.wavelength
#Inclinacion de las franjas
Xrot, Yrot = self.__rotar__(angulo)

#Calculo de la pendiente
pendiente = altura / periodo
#Calculo de la altura
h = Xrot * pendiente

#Calculo del a fase


fase = k * (indice - 1) * h
#Definicion del origen
fase = fase - fase.min()
#Normalizacion entre 0 y 2pi
fase = np.remainder(fase, 2 * sp.pi)
self.u = sp.exp(1j * fase)

Si llamamos a esta funcin se obtiene


def ejemplo_redBlazed():
x = sp.linspace(-250 * um, 250 * um, 512)
y = sp.linspace(-250 * um, 250 * um, 512)
wavelength = 0.6238 * um
periodo = 100 * um
t = mascaraXY(x, y, wavelength)
t.red_blazed(periodo= periodo, altura=2 * um, indice=1.5, angulo=0 * grados)
t.dibujar(tipo=fase, titulo=red blazed)

15.5. Red Blazed 239


PIMCD2013-python, Publicacin 1.0

red blazed
200 2.4

1.6
100
0.8
y(m)

0 0.0

0.8
100
1.6

200 2.4

200 100 0 100 200


x(m)

15.6 Red bidimensional

Una red bidimensional es aquella constituida por un conjunto de franjas verticales y horizontales, tales que per-
mite la transmisin de luz nicamente en dichas franjas. La implementacin es sencilla basta con definir los dos
conjuntos de franjas horizontal y vertical y superponerlas. La superposicin es equivalente a multiplicar las franjas
puesto que cada una es un matriz de ceros (no hay transmisin) y unos (transmisin permitida.
def red2D(self, periodo = 40.*um, amin = 0, amax = 1., desfase = 0.*sp.pi / 2, x0 = 0, fil
#Se inicializa
t1 = mascaraXY(self.x, self.y, self.wavelength);
t2 = mascaraXY(self.x, self.y, self.wavelength);
#Red horizontal
t1.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo)
#Red vertical
t2.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo + 90.*grados)
#Red binaria
self.u = t1.u * t2.u

La representacin de la red bidimensional queda


def ejemplo_red2D():
x = sp.linspace(-250 * um, 250 * um, 512)
y = sp.linspace(-250 * um, 250 * um, 512)
wavelength = 0.6238 * um
periodo = 50 * um
t = mascaraXY(x, y, wavelength)
t.red2D(periodo=periodo, amin=0, amax=1., desfase=0 * sp.pi / 2,\
x0=0, fillFactor=0.5, angulo=0 * grados)
t.dibujar(tipo=intensidad, titulo=red 2D)

240 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

red 2D
1.0
200 0.9
0.8
100 0.7
0.6
y(m)

0 0.5
0.4
100 0.3
0.2
200 0.1

200 100 0 100 200 0.0


x(m)

15.7 Red tipo Ajedrez

Como su propio nombre indica una red tipo ajedrez genera un damero con regiones de transmitancia unidad y
nula. Debido a como se ha definido la funcin, se pueden implementar distintos tipos de dameros con regiones de
transmitancia mayores y menores como se muestra en el ejemplo. La implementacin del a funcin es completa-
mente anloga a la de la red bidimensional cambiando nicamente la ltima lnea del cdigo, en la cual en vez de
realizar el producto de las dos matrices, se realiza una funcin xor entre ellas. Esta funcin toda dos argumentos
binarios, y su resultado nicamente nulo cuando los dos argumentos adquieren simultneamente el mismo valor
(0,0), o (1,1), de lo contrario el resultado es la unidad.
def red2D_ajedrez(self, periodo = 40 * um, amin = 0, amax = 1, desfase = 0 * sp.pi / 2,\
x0 = 0, fillFactor = 0.75, angulo = 0 * grados):
#Mismo proceder que en 2D
t1 = mascaraXY(self.x, self.y, self.wavelength);
t2 = mascaraXY(self.x, self.y, self.wavelength);
t1.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo)
t2.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo + 90.*grados)
#Actuacion de la XOR
self.u = sp.logical_xor(t1.u, t2.u)

As resulta la representacin
def ejemplo_redAjedrez1():
x = sp.linspace(-250 * um, 250 * um, 1024)
y = sp.linspace(-250 * um, 250 * um, 1024)
wavelength = 0.6238 * um
periodo = 50 * um
t = mascaraXY(x, y, wavelength)
t.red2D_ajedrez(periodo=periodo, amin=0, amax=1., desfase=0 * sp.pi / 2, x0=0,\

15.7. Red tipo Ajedrez 241


PIMCD2013-python, Publicacin 1.0

fillFactor=0.5, angulo=0 * grados)


return t

red 1 red 2
200 200

100 100

0 0

100 100

200 200
200 100 0 100 200 200 100 0 100 200

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Para definir el segundo dibujo los parmetros resultan


t.red2D_ajedrez(periodo=periodo, amin=0, amax=1., desfase=0 * sp.pi / 2, x0=0, fillFactor=0
angulo=45 * grados)

15.8 Red radial

Las redes de difraccin tambin pueden tener simetra radial. Son parecidos a los axicones, pero con transmitancia
1 o 0.
def red_radial(self, r0 = (0 * um, 0 * um), periodo = 20 * um, desfase=0*um, radius=400*um
#si solamente hay un numero, es que las posiciones y radios son los mismos para am
if len(r0) == 1:
r0 = (r0[0], r0[0])
#Vector de onda
k = 2 * sp.pi / self.wavelength
x0, y0 = r0
#Distancia de la generatriz al eje del cono
r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
#hago un seno y luego binarizo
t = 0.5*(1+sp.sin(2*sp.pi*(r+desfase)/periodo))
if binaria==True:
i0 = t <= 0.5; t[i0] = 0
i1 = t > 0.5; t[i1] = 1
#Region de transmitancia
u = sp.zeros(sp.shape(self.X))
ipasa = r < radius
u[ipasa] = 1
self.u = u * t

As resulta la representacin
def ejemplo_red_radial():
ndatos = 512
tamano = 250 * um
x = sp.linspace(-tamano / 2, tamano / 2, ndatos)

242 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

y = sp.linspace(-tamano / 2, tamano / 2, ndatos)


wavelength = 0.6328 * um

t1 = mascaraXY(x, y, wavelength)
t1.red_radial(r0 = (0 * um, 0 * um), periodo=20*um, desfase=10*um, radius = 100 * um)
t1.dibujar(tipo = intensidad)

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)

15.9 Red angular

Las redes de difraccin tambin pueden tener simetra angular. El periodo va en grados.
def red_angular(self, r0 = (0 * um, 0 * um), periodo = 20*grados, desfase=0*grados, radius
#si solamente hay un numero, es que las posiciones y radios son los mismos para am
if len(r0) == 1:
r0 = (r0[0], r0[0])
#Vector de onda
k = 2 * sp.pi / self.wavelength
x0, y0 = r0
#Distancia de la generatriz al eje del cono
r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
theta=sp.arctan((self.Y - y0)/(self.X - x0))
#Region de transmitancia
t = (1+sp.sin(2*sp.pi*(theta-desfase)/periodo))/2
if binaria==True:
i0 = t <= 0.5; t[i0] = 0
i1 = t > 0.5; t[i1] = 1

u = sp.zeros(sp.shape(self.X))
ipasa = r < radius
u[ipasa] = 1

15.9. Red angular 243


PIMCD2013-python, Publicacin 1.0

self.u = u * t

As resulta la representacin

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)

15.10 Red con borde sinusoidal

Este tipo de redes puede tener incidencia para eliminar armnicos en la direccin x
def red_borde_sinusoidal(self, r0 = (0 * um, 0 * um), periodo = 20*grados, lp=10*um, ap=2*
#si solamente hay un numero, es que las posiciones y radios son los mismos para am
#lp es la longitud del periodo del borde, ap es la amplitud del periodo del borde
if len(r0) == 1:
r0 = (r0[0], r0[0])
#Vector de onda
k = 2 * sp.pi / self.wavelength
x0, y0 = r0
#Distancia de la generatriz al eje del cono
r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
theta=sp.arctan((self.Y - y0)/(self.X - x0))
#Region de transmitancia
Desfase=desfase+ap*sp.sin(2*sp.pi*self.Y/lp)

t = (1+sp.sin(2*sp.pi*(self.X-Desfase)/periodo))/2
if binaria==True:
i0 = t <= 0.5; t[i0] = 0
i1 = t > 0.5; t[i1] = 1

u = sp.zeros(sp.shape(self.X))
ipasa = r < radius

244 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

u[ipasa] = 1

self.u = u * t

As resulta la representacin, se produce una variacin perodica del desfase.


def ejemplo_red_borde_sinusoidal():
ndatos = 1024
tamano = 250 * um
x = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y = sp.linspace(-tamano / 2, tamano / 2, ndatos)
wavelength = 0.6328 * um
t1 = mascaraXY(x, y, wavelength)
t1.red_borde_sinusoidal(r0 = (0 * um, 0 * um), periodo = 20*um, lp=20*um, ap=10*um, desfas
t1.dibujar(tipo = intensidad)

1.0
100 0.9
0.8
50 0.7
0.6
y(m)

0 0.5
0.4
50 0.3
0.2
100 0.1

100 50 0 50 100 0.0


x(m)

15.11 Red hiperblica

def red_hiperbolica(self, r0 = (0 * um, 0 * um), periodo = 20*grados, desfase=0*grados, ra


#si solamente hay un numero, es que las posiciones y radios son los mismos para am
if len(r0) == 1:
r0 = (r0[0], r0[0])
#Vector de onda
k = 2 * sp.pi / self.wavelength
x0, y0 = r0
#Distancia de la generatriz al eje del cono

15.11. Red hiperblica 245


PIMCD2013-python, Publicacin 1.0

#rotacion de la lente
Xrot, Yrot = self.__rotar__(angulo)

r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)


x_posiciones = sp.sqrt(abs((Xrot - x0) ** 2 - (Yrot - y0) ** 2))
#Region de transmitancia
t = (1+sp.sin(2*sp.pi*x_posiciones/periodo))/2
if binaria==True:
i0 = t <= 0.5; t[i0] = 0
i1 = t > 0.5; t[i1] = 1

u = sp.zeros(sp.shape(self.X))
ipasa = r < radius
u[ipasa] = 1

self.u = u * t

As resulta la representacin, se produce una variacin perodica del desfase.


def ejemplo_red_hiperbolica(periodo=20*um, potencia=2):
ndatos = 512
tamano = 200 * um
x = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y = sp.linspace(-tamano / 2, tamano / 2, ndatos)
wavelength = 0.6328 * um

t1 = mascaraXY(x, y, wavelength)
t1.red_hiperbolica( r0 = (0 * um, 0 * um), periodo = 10*um, desfase=45*grados, radius=200*
t1.dibujar(tipo=intensidad)

100 1.0
0.9
0.8
50
0.7
0.6
y(m)

0 0.5
0.4
0.3
50
0.2
0.1
100100 50 0 50 100 0.0
x(m)

246 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

15.12 Aplicacin como redes de difraccin en campo lejano

El efecto de las interferencias surge directamente de que las ecuaciones de Maxwell son lineales en los campos
elctricos y magnticos. Supongamos que E1 y E2 son soluciones. Entonces

2


donde a es el tamao mximo del elemento difractor. Bajo esta aproximacin, el campo difractado se puede
calcular como una integral
2 + 2
(+ 2 )

E(, , ) = E0 (, ) (+) .

donde E0 (, ) es el campo justo a la salida del elemento difractor.


La aproximacin ms usual para este campo es considerar que se obtiene como el producto del campo incidente
E (, ) por el coeficiente de transmisin del mscara (, )E (, )

E (, ) = (, )E (, ).

La gran ventaja de esta ecuacin es que se puede escribir como una transformada de Fourier, que es una operacin
bastante conocida en matemticas
2 + 2
(+ 2 )
E(, , ) = [E0 (, )] .

Como el primer trmino delante de la transformada de Fourier es casi constante para un plano z determinado, se
suele eliminar.

15.12.1 Difraccin por una red de sinusoidal

La red sinusoidal tiene solamente tres frecuencias espaciales, que son las que se observan en la figura de difraccin.
def difraccion_red_seno():
#tamano de area de visualizacion
tamano = 1000 * um
ndatos = 512
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
#longitud de onda
lambda0 = 0.6238 * um

#fuente de iluminacion
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

#mascara
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.red_seno(periodo=40*um)
u2 = u1 * t1

u3 = u2.fft(quitar0 = False)

u2.dibujar()

punto1=(u3.x.min(),0)
punto2=(u3.x.max(),0)

u3.dibujar_perfil(punto1,punto2, normalizar=maximo, order=2)

15.12. Aplicacin como redes de difraccin en campo lejano 247


PIMCD2013-python, Publicacin 1.0

Tras ejecutar el cdigo se obtiene la mscara y el perfil de intensidades en la pantalla.

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)

0.8

0.6
Intensidad

0.4

0.2

0.0

1500 1000 500 0 500 1000 1500


h (perfil)
248 Captulo 15. Redes de Difraccin
PIMCD2013-python, Publicacin 1.0

15.12.2 Difraccin por una red de Ronchi

La red de Ronchi tiene ms frecuencias espaciales, todas equidistanciadas, que son las que se observan en la figura
2
de difraccin. La altura de cada pico es el cuadrado del valor del coeficiente de Fourier , = | | .
def difraccion_red_ronchi():
#tamano de area de visualizacio
tamano = 1000 * um
ndatos = 512
x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
#longitud de onda
lambda0 = 0.6238 * um

#fuente de iluminacion
u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

#mascara
t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
t1.red_ronchi( periodo = 40 * um, x0 = 0 * um, fillFactor = 0.5, angulo = 0 * grados)
u2 = u1 * t1

u3 = u2.fft(quitar0 = False)

u2.dibujar()

punto1=(u3.x.min(),0)
punto2=(u3.x.max(),0)

u3.dibujar_perfil(punto1,punto2, normalizar=maximo, order=2)

Tras ejecutar el cdigo se obtiene la mscara y el perfil de intensidades en la pantalla.

15.12. Aplicacin como redes de difraccin en campo lejano 249


PIMCD2013-python, Publicacin 1.0

1.0
400 0.9
0.8
200 0.7
0.6
y(m)

0 0.5
0.4
200 0.3
0.2
400 0.1

400 200 0 200 400 0.0


x(m)

0.8

0.6
Intensidad

0.4

0.2

0.0

1500 1000 500 0 500 1000 1500


h (perfil)

250 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

15.13 Efecto Talbot

Para conocer la distribucin de intensidad en campo cercano utilizaremos la aproximacin de Fresnel (ver di-
fraccin en campo cercano), considerando la invariancia de la red de difraccin en el eje . Entonces el campo
difractado se puede calcular a partir de

2
E (, ) = E0 () 2 ()

Resolviendo la integral para la estructura peridica de una red de difraccin, el campo resulta
( ) ( )

E (, ) = exp 2 exp 22 2
2
=

y, por tanto, la intensidad


[ ] [ ]
)
* 2
( 2
(, ) = exp 2 ( ) exp 2
22
= =

Esta ecuacin se ha implementado numricamente para observar el aspecto de la distribucin de intensidad en


campo cercano producido por una red de difraccin.

150
5.6
100
4.8
50 4.0
x (microns)

0 3.2

2.4
50
1.6
100
0.8

1500 2000 4000 6000 8000 10000 0.0


z (microns)
En la figura se observa el fenmeno de las autoimgenes, al ser peridico en el eje z. Se forman rplicas de la red
a distancias conocidas como distancia de Talbot, que resulta ser

= 22 /.

La parte principal del cdigo, que es la obtencion del campo, es la siguiente

15.13. Efecto Talbot 251


PIMCD2013-python, Publicacin 1.0

def efectoTalbot(t, z, periodo=40*um):


""" esta funcion calcula el efecto talbot"""

zT=2*periodo**2/t.wavelength
X,Z=sp.meshgrid(t.x,z)
periodo=50*um
ordenes=sp.array([-3, -1, 0, 1, 3])
coefs=sp.array([.25, 0.5, 1, 0.5, .25])

red=sp.transpose([ordenes, coefs])
u2=sp.zeros(X.shape,complex)

for j2,aj in red:


u2+=aj*sp.exp(1j*2*sp.pi*j2*X/periodo)*sp.exp(-1j*2*sp.pi*j2**2*Z/zT)

campoxz=sp.real(u2)
return campoxz

Podemos observar el aspecto de las automgenes simplemente calculando la distribucin de intensidad en campo
cercano mediante la aproximacin de Rayleigh-Sommerfeld. Esto lo hemos hecho para 3 distancias significativas
en la red de Ronchi, , /2 y /4:
efecto talbot
zT zT/2 zT/4
100 100 100
50 50 50
0 0 0
50 50 50
100 100 100
100 50 0 50 100 100 50 0 50 100 100 50 0 50 100

0.00.10.20.30.40.50.60.70.80.91.0 0.00.10.20.30.40.50.60.70.80.91.0 0.10.20.30.40.50.60.70.80.91.0

Veamos ahora que ocurre cuando sobre la red de difraccin se incide con un haz gaussiano. Al propagarse la luz,
los distintos rdenes de tamao finito, empiezan a no interferir entre s, al no estar espacialmente en la mismas
posiciones. Entonces, deja de producirse el fenmeno interferencial y tenemos los distintos ordenes aislados. Esto
ocurre en campo cercano, y no solamente cuando estamos muy lejos de la red.

252 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

zT efecto talbot 2zT


200 200
100 100
0 0
100 100
200 200
200 100 0 100 200 200 100 0 100 200
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
3zT 4zT
200 200
100 100
0 0
100 100
200 200
200 100 0 100 200 200 100 0 100 200
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

15.14 Efectos con dos redes

Los sistemas de doble red se utilizan frecuentemente en metrologa ptica, como en deflectometra moir para
medir la topografa 3D de objetos o en sistemas Talbot, Lau o autoimgenes generalizadas para medir desplaza-
mientos con gran precisin.
Veremos ahora algunos efectos de doble red. En el desplazamiento Talbot (movimiento de dos redes cuando es
iluminado con onda plana). Se muestra una animacin

15.14. Efectos con dos redes 253


PIMCD2013-python, Publicacin 1.0

200

100

100

200

400 200 0 200 400

Otro efecto interesante es el efecto vernier, donde aparecen franjas cuando a) el periodo de las dos redes es distinto
y b) el ngulo entre las dos redes es distinto.
Se muestra estos dos casos mostrando una imagen y una animacin:
Distinto periodo:

254 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

efecto vernier

1000

500
y(m)

500

10002000 1500 1000 500 0 500 1000 1500 2000


x(m)

100

200

300

400

500
0 100 200 300 400 500

Distinto ngulo:

15.14. Efectos con dos redes 255


PIMCD2013-python, Publicacin 1.0

efecto vernier
1000

500
y(m)

500

10001000 500 0 500 1000


x(m)
0

100

200

300

400

500
0 100 200 300 400 500

Estos dos efectos permiten medir (macroscpicamente) el desplazamiento, puesto que las franjas de vernier (las

256 Captulo 15. Redes de Difraccin


PIMCD2013-python, Publicacin 1.0

grandes) se desplazan de forma amplificada al desplazamiento relativo entre las redes.

400

200

200

400

400 200 0 200 400

400

200

200

400

400 200 0 200 400

15.14. Efectos con dos redes 257


PIMCD2013-python, Publicacin 1.0

258 Captulo 15. Redes de Difraccin


CAPTULO 16

Procesado ptico de la informacin

Autor Luis Miguel Snchez Brea


Revisor Jos Luis Vilas Prieto
Se entiende por procesado de imgenes a cualquier transformacin que pueda ser realizada en la imagen ya sea
esta digital u ptica. El procedimiento para cualquiera de los dos tipos de imgenes es el mismo, y en gran parte
del procesado de imgenes implica pasar al espacio de frecuencias es decir, realizar la transformada de Fourier. Se
puede probar como un haz colimado focaliza en el foco de la lente, obtenindose en dicho punto la transformada
de Fourier del objeto. La transformada de Fourier de la imagen, contiene la misma informacin pero en el espacio
de frecuencias, ubicndose en los bajos rdenes de difraccin las bajas frecuencias los cuales se corresponden con
la imagen general del objeto. As mismo todos aquellos puntos alejados del origen, esto es los ordenas ms altos de
difraccin representan aquellos pequeos detalles de la imagen, por tanto si se eliminan se pierde definicin pero
se mantiene la estructura de la imagen. El objetivo de los filtros de frecuencias consiste en obtener la transformada
de Fourier de una imagen y tapar la regin de la transformada con las frecuencias a eliminar, finalmente se realizar
la transformada inversa para recuperar la imagen filtrada.

Contenidos de este captulo:


Funcionamiento de la clase procesadoOptico
Filtro pasa baja
Eliminacin de ruido
Filtro pasa alta
Filtro pasa banda
Filtro de contraste de fase

Herramientas utilizadas en este tutorial:


scipy: manipulacin de arrays de datos.
matplotlib.pyplot: generacin de dibujos similar a Matlab.
fuentesXY: Definicin de haces de luz.
camposXY: Diversas funciones de tratamiento de imgenes e inicializacin.
Archivos necesarios para el procesado de imgenes:
Archivo con las funciones principales procesadoOptico.py
Ejemplo filtro pasa baja test_filtroPasaBaja.py
Ejemplo filtro deteccin de bordes test_filtroPasaAlta.py
Ejemplo filtro pasa Banda test_filtroPasaAlta2.py
Ejemplo filtro pasa Banda test_filtroPasaBanda.py
Ejemplo filtro de eliminacin de ruido test_filtroEliminarRuido.py
Ejemplo filtro contraste de fase test_filtroContrasteFase.py

259
PIMCD2013-python, Publicacin 1.0

Contenidos de los archivos:


procesadoOptico.py:
procesar(). Realiza el procesamiento de la imagen, desde la definicin del campo inicial, el plano
de Fourier, la aplicacin del filtro y la obtencin del campo filtrado.
dibujar(). Representa el proceso de filtrado, intensidad del objeto, su fase, el plano de Fourier, el
filtro de intensidad, el filtro de fase y el campo filtrado.
dibujarCampoFiltrado (). Representa el campo filtrado.

16.1 Funcionamiento de la clase procesadoOptico

A continuacin se muestran una serie de funciones necesarias para el procesado ptico.


Al igual que en un experimento fsico se dispone de una fuente, un objeto y un filtro, en simulacin es preciso
definir estos parmetros del experimento para realizar un procesamiento ptico de la imagen. As se inicia la
clase con la funcin __init__ especificando tales condiciones. Esta funcin dispone de un if, de modo que en
ausencia de cualquiera de estos tres elementos no se realice filtrado alguno.
def __init__(self, fuente, objeto, filtro):
"""Se inicia un nuevo experimento"""
#Se definen los parametros de describen la fuente, el objeto y el filtro
self.fuente = fuente
self.objeto = objeto
self.filtro = filtro

#Si alguno de ellos falla no puede realizarse procesamiento alguno


if fuente == None or objeto == None or filtro == None:
self.planoFourier = None
self.campoFiltrado = None
else:
self.procesar()

As mismo se define la funcin de procesamiento, la cual calcula el campo producto del objeto con la ilumi-
nacin. Puesto que se trabaja en el plano focal y en este se obtiene la transformada de Fourier del objeto bajo
un haz colimado, se calcula la transformada de Fourier. Finalmente se aplica el filtro realizando el producto de
la transformada de Fourier por la funcin filtro. Finalmente, se deshace la transformada, para obtener el campo
filtrado.
def procesar(self):
#Campo inicial
campoInicial = self.fuente * self.objeto

#Transformada de Fourier del campo inicial


planoFourier = campoInicial.fft(quitar0 = False, shift = True)

#Aplicacion del filtro


planoFourierFiltrado = planoFourier * self.filtro

#Transformada de Fourier para obtener el campo filtrado


campoFiltrado = planoFourierFiltrado.fft(quitar0 = True, shift = False)

self.planoFourier = planoFourier
self.campoFiltrado = campoFiltrado

Resta realizar una representacin de los campos a fin de comprar el incidente y el filtrado, esto se lo hace la funcin
dibujar. As se genera un array de imgenes donde se ubicarn el objeto, su fase, la transformada de Fourier,
el filtro de intensidad, el filtro de fase y finalmente el campo filtrado. As se selecciona la componente del array
donde representar la imagen (objeto, fase, transformada de Fourier...). Finalmente se dibuja con plt, el resto de
comandos determinan el ttulo, los ejes, entre otros.

260 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

def dibujar(self, nombreArchivo = ):


#Se crea uan figura
id = plt.figure(figsize = (9, 6), facecolor = w, edgecolor = k)

#objeto intensidad
#Seleccion de la region dela figura donde se pretende representar
plt.subplot(2, 3, 1)
#Intensidad
dibujo = abs(self.objeto.u) ** 2
#Representacion
so=self.objeto
h1 = plt.imshow(dibujo, interpolation = bilinear, aspect = auto,
origin = lower, extent = [so.x.min(), so.x.max(), so.y.min(),\

#Titulo
plt.title(objeto intensidad, fontsize = 18)
#Seleccion del mapa de color
h1.set_cmap("gist_heat") #RdBu
#Los ejes no se representan
plt.axis(off)

#objeto fase
plt.subplot(2, 3, 2)
dibujo = sp.angle(self.objeto.u)
#Representacion
h1 = plt.imshow(dibujo, interpolation = bilinear, aspect = auto,
origin = lower, extent = [so.x.min(), so.x.max(), so.y.min(),\

#Titulo
plt.title(objeto fase, fontsize = 18)
#Seleccion del mapa de color
h1.set_cmap("RdBu") #RdBu
#Los ejes no se representan
plt.axis(off)

#filtro intensidad
plt.subplot(2, 3, 4)
#Intensidad
dibujo = abs(self.filtro.u) ** 2
#Representacion
sf=self.filtro
h1 = plt.imshow(dibujo, interpolation = bilinear, aspect = auto,\
origin = lower, \
extent = [sf.x.min(), sf.x.max(), sf.y.min(), sf.y.max()])
#Titulo
plt.title(filtro intensidad, fontsize = 18)
#Seleccion del mapa de color
h1.set_cmap("gist_heat") #RdBu
#Los ejes no se representan
plt.axis(off)

#filtro fase
plt.subplot(2, 3, 5)
dibujo = sp.angle(self.filtro.u)
#Representacion
h1 = plt.imshow(dibujo, interpolation = bilinear, aspect = auto,
origin = lower, extent = [sf.x.min(), sf.x.max(), sf.y.min(),\

#Titulo
plt.title(filtro fase, fontsize = 18)
#Seleccion del mapa de color
h1.set_cmap("RdBu") #RdBu
#Los ejes no se representan

16.1. Funcionamiento de la clase procesadoOptico 261


PIMCD2013-python, Publicacin 1.0

plt.axis(off)

#planoFourier
plt.subplot(2, 3, 3)
dibujo = sp.log(abs(self.planoFourier.u) ** 2 + 1)
#Representacion
pf=self.planoFourier
h1 = plt.imshow(dibujo, interpolation = bilinear, aspect = auto,
origin = lower, extent = [pf.x.min(), pf.x.max(), pf.y.min(),\

plt.title(plano Fourier, fontsize = 18)


#Seleccion del mapa de color
h1.set_cmap("gist_heat") #RdBu
#Los ejes no se representan
plt.axis(off)

#campoFiltrado
plt.subplot(2, 3, 6)
dibujo = sp.fliplr(sp.flipud(abs(self.campoFiltrado.u) ** 2))
#Representacion
cf=self.campoFiltrado
h1 = plt.imshow(dibujo, interpolation = bilinear, aspect = auto,
origin = lower, extent = [cf.x.min(), cf.x.max(), cf.y.min(),\

#Titulo
plt.title(campo Filtrado, fontsize = 18)
#Seleccion del mapa de color
h1.set_cmap("gist_heat") #RdBu
#Los ejes no se representan
plt.axis(off)

if not nombreArchivo == :
plt.savefig(nombreArchivo, dpi = 100, bbox_inches = tight,\
pad_inches = 0.1)

16.2 Filtro pasa baja

Un filtro pasa es aquel que atena las altas frecuencias y permitiendo nicamente el paso de las bajas frecuencias.
De este modo, un filtro pasa baja conserva los detalles ms generales de la imagen, eliminando los pequeos
detalles. Esto se logra en el plano de Fourier diafragmando los mayores rdenes de difraccin, por ser estos los
correspondientes a altas frecuencias. En las imgenes de plano Fourier y filtro intensidad se puede apreciar este
hecho. La abertura del filtro de intensidad se ubica en el plano de Fourier, atravesando el filtro las bajas frecuencias.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""Simulaciones relacionadas con la leccion de filtrado optico"""

#Importacion de paquetes y librerias


import locale
locale.setlocale(locale.LC_NUMERIC, C)
import sys
sys.path.append(../)
import scipy as sp
from procesadoOptico import *
from fuentesXY import fuenteXY

262 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

from mascarasXY import mascaraXY

#Tamano
tamano = 1000 * um
x0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)
y0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)

#Definicion de la fuente
fuente1 = fuenteXY(x=x0, y=y0)
fuente1.onda_plana(A=1, theta=0*grados, phi=0*grados)

def test_filtroPasaBaja(): #amplitud


#Definicion del objeto
objeto = mascaraXY(x=x0, y=y0)
objeto.imagen(nombre=lena.png, normalizar=True, canal=0, tamanoImagen=False, invertir=Fa
#Definicion del filtro
filtro = mascaraXY(x=x0, y=y0)
filtro.circulo(r0=(0*um,0*um), radius=(20*um,20*um), angulo=0*grados)
#Campo filtrado, procesado
p1=procesadoOptico(fuente1, objeto, filtro)
p1.dibujar2(idfigs=(1,0,2,3,0,4))
p1.dibujarCampoFiltrado()

if __name__ == __main__:
test_filtroPasaBaja()
plt.show()

objeto intensidad FFT

filtro intensidad Imagen

16.2. Filtro pasa baja 263


PIMCD2013-python, Publicacin 1.0

16.3 Eliminacin de ruido

Una aplicacin interesante del filtro pasa baja es la eliminacin de ruido en una imagen. Para comprobarlo, toma-
mos la foto de lena.png y aadimos un ruido aleatorio.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""Simulaciones relacionadas con la leccion de filtrado optico"""

#Carga de paquetes y librerias


import locale
locale.setlocale(locale.LC_NUMERIC, C)
import sys
sys.path.append(../)
import scipy as sp
from procesadoOptico import *

264 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

from fuentesXY import fuenteXY


from mascarasXY import mascaraXY

tamano = 1000 * um
x0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)
y0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)

def test_filtroEliminarRuido():
#Definicion de la fuente
fuente1 = fuenteXY(x=x0, y=y0)
fuente1.onda_plana(A=1, theta=0*grados, phi=0*grados)
#Definicion del objeto
objeto = mascaraXY(x=x0, y=y0)
objeto.imagen(nombre=lena.png, normalizar=True, canal=0, tamanoImagen=False, invertir=Fa
objeto.u=objeto.u+sp.rand(len(x0),len(y0))
#Definicion del filtro
filtro = mascaraXY(x=x0, y=y0)
filtro.circulo(r0=(0*um,0*um), radius=(50*um,50*um), angulo=0*grados)
#Campo filtrado, procesado de la imagen
p1=procesadoOptico(fuente1, objeto, filtro)
p1.dibujar2(idfigs=(1,0,2,3,0,4))
p1.dibujarCampoFiltrado()

test_filtroEliminarRuido()
plt.show()

objeto intensidad FFT

filtro intensidad Imagen

16.3. Eliminacin de ruido 265


PIMCD2013-python, Publicacin 1.0

16.4 Filtro pasa alta

Este tipo de filtro es el opuesto al filtro pasa baja, conserva las altas frecuencias y atena las bajas. De este modo,
los detalles ms gruesos de la imagen ser pierden, pero los pequeos se mantienen. Por ejemplo un conjunto de
franjas equiespaciadas muy separadas entre s, se atenuaran respecto de otro conjunto de franjas poco espaciadas
entre s. La consecucin de este tipo de filtro se logra tapando los rdenes ms bajos de difraccin en el plano de
Fourier, atravesando nicamente el filtro, los ms altos. Nuevamente, vase la imagen, como el plano de Fourier el
filtro de intensidad tapa dichos rdenes, de modo que el campo filtrado muestra los pequeos detalles de la imagen
(altas frecuencias).
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""Simulaciones relacionadas con la leccion de filtrado optico"""

#Carga de librerias y paquetes

266 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

import sys
sys.path.append(../)
from procesadoOptico import *
from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

#Tamano
tamano = 1000 * um
x0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)
y0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)

def test_filtroPasaAlta():
#Definicion de la fuente
fuente1 = fuenteXY(x=x0, y=y0)
fuente1.onda_plana(A=1, theta=0*grados, phi=0*grados)
#Definicion del Objeto
objeto = mascaraXY(x=x0, y=y0)
objeto.imagen(nombre=lena.png, normalizar=True, canal=0, tamanoImagen=False, invertir=Fa
#Definicion del filtro
filtro = mascaraXY(x=x0, y=y0)
filtro.circulo(r0=(0*um,0*um), radius=(50*um,50*um), angulo=0*grados)
filtro.inversaAmplitud()
#Campo filtrado, procesado de la imagen
p1=procesadoOptico(fuente1, objeto, filtro)
p1.dibujar2(idfigs=(1,0,2,3,0,4))
p1.dibujarCampoFiltrado()

test_filtroPasaAlta()
plt.show()

16.4. Filtro pasa alta 267


PIMCD2013-python, Publicacin 1.0

objeto intensidad FFT

filtro intensidad Imagen

268 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

veamos otro ejemplo de deteccin de bordes, donde stos estn ms definidos.


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""Simulaciones relacionadas con la leccion de filtrado optico"""

#Carga de librerias y paquetes


import sys
sys.path.append(../)
from procesadoOptico import *
from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

tamano = 1000 * um
x0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)
y0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)

def test_filtroPasaAlta2():

16.4. Filtro pasa alta 269


PIMCD2013-python, Publicacin 1.0

#Definicion de la fuente
fuente1 = fuenteXY(x=x0, y=y0)
fuente1.onda_plana(A=1, theta=0*grados, phi=0*grados)
#Definicion del bjeto
objeto = mascaraXY(x=x0, y=y0)
objeto.cuadrado(r0=(0,0), size=(250*um,250*um), angulo=45*grados)
#Definicion del filtro
filtro = mascaraXY(x=x0, y=y0)
filtro.circulo(r0=(0*um,0*um), radius=(40*um,40*um), angulo=0*grados)
filtro.inversaAmplitud()
#Campo filtrado, procesamiento de la imagen
p1=procesadoOptico(fuente1, objeto, filtro)
p1.dibujar2(idfigs=(1,0,2,3,0,4))
p1.dibujarCampoFiltrado()

test_filtroPasaAlta2()
plt.show()

objeto intensidad FFT

filtro intensidad Imagen

270 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

16.5 Filtro pasa banda

Los filtros pasa banda se ubican entre los filtros pasa alta y los filtros pasa baja, permitiendo nicamente el paso de
frecuencias dentro de una banda espectral, filtrando las altas y las bajas frecuencias. Para ello, se bloquean en el
plano de Fourier los bajos y altos rdenes de difraccin, as el filtro de intensidad tendr forma de corona circular,
siendo los puntos interiores a la corona, aquellos que permiten en paso de luz.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/10/24 (version 1.0)
# Licencia: GPL
#-------------------------------------
"""Simulaciones relacionadas con la leccion de filtrado optico"""

#Carga de librerias y paquetes


import sys
sys.path.append(../)
from procesadoOptico import *

16.5. Filtro pasa banda 271


PIMCD2013-python, Publicacin 1.0

from fuentesXY import fuenteXY


from mascarasXY import mascaraXY

tamano = 1000 * um
x0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)
y0 = sp.linspace(-tamano/2 * um, tamano/2 * um, 512)

def test_filtroPasaBanda(): #amplitud


#Definicion de la fuente
fuente1 = fuenteXY(x=x0, y=y0)
fuente1.onda_plana(A=1, theta=0*grados, phi=0*grados)
#Definicion del objeto
objeto = mascaraXY(x=x0, y=y0)
objeto.imagen(nombre=lena.png, normalizar=True, canal=0, tamanoImagen=False, invertir=Fa
#Definicion del filtro
filtro = mascaraXY(x=x0, y=y0)
filtro.anillo(r0=(0*um,0*um), radius1=(50*um,50*um), radius2=(80*um,80*um), angulo=0*grado
#Campo filtrado, procesado de la imagen
p1=procesadoOptico(fuente1, objeto, filtro)
p1.dibujar2(idfigs=(1,0,2,3,0,4))
p1.dibujarCampoFiltrado()

test_filtroPasaBanda()
plt.show()

objeto intensidad FFT

filtro intensidad Imagen

272 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

16.6 Filtro de contraste de fase

Un filtro de contraste de fase potencia las diferencias de fase entre las distintas regiones del objeto. Para ello se
ilumina el objeto con luz colimada y se introduce una lmina/anillo desfasador posterior al sistema de iluminacin,
el objetivo de este anillo es retardar la fase de la luz.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor: Luis Miguel Sanchez Brea
# Fecha 2013/12/10 (version 1.5) - dibujar 2
# Licencia: GPL
#-------------------------------------
"""Simulaciones relacionadas con la leccion de filtrado optico"""

#Carga de librerias y paquetes


import sys
sys.path.append(../)
from procesadoOptico import *
from fuentesXY import fuenteXY
from mascarasXY import mascaraXY

16.6. Filtro de contraste de fase 273


PIMCD2013-python, Publicacin 1.0

def filtroContrasteFase():
#Definicion de la fuente
fuente1 = fuenteXY(x=x0, y=y0)
fuente1.onda_plana(A=1, theta=0*grados, phi=0*grados)
#Definicion del objeto
objeto = mascaraXY(x=x0, y=y0)
objeto.imagen(nombre=lena.png, normalizar=True, canal=0, tamanoImagen=False, invertir=Fa
objeto.setFase(q=1, fase_min=0, fase_max=sp.pi)
#Definicion del filtro
filtro = mascaraXY(x=x0, y=y0)
filtro.circulo(r0=(0*um,0*um), radius=(4*um,4*um), angulo=0*grados)
filtro.setFase(q=1, fase_min=0, fase_max=sp.pi)
#Campo filtrado y procesado de la imagen
p1=procesadoOptico(fuente1, objeto, filtro)
p1.dibujar2(idfigs=(0,1,2,0,3,4))
p1.dibujarCampoFiltrado()
filtroContrasteFase()
plt.show()

objeto fase FFT

filtro fase Imagen

274 Captulo 16. Procesado ptico de la informacin


PIMCD2013-python, Publicacin 1.0

16.6. Filtro de contraste de fase 275

Вам также может понравиться