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

Fsica Computacional

Erick Contreras Pasten


25 de julio de 2013
2
Introducci on
El estudio de la fsica, en todas las ramas de investigacion que esta tiene, se divide en: un estudio
teorico, el cual va enfocado a que con la ayuda de la matematica y la exploracion de la propia mente
humana, se generen nuevas ideas y teoras que permitan describir como esta contruido el mundo en
el cual nos encontramos; y un estudio experimental, el cual se centra en comprobar o refutar las ideas
propuestas por la fsica te orica, por medio del an alisis de datos tanto de experimentos reales como de
simulaciones, as como tambien dar indicios para la conformacion de nuevas teoras. Adem as, hoy en
da se requiere una gran cantidad de fsicos experimentales.
En la actualidad, debido a la complejidad de los experimentos que se necesitan realizar, la programa-
cion se hace una herramienta indispensable que debe conocer cualquier cientco para poder realizar
sus investigaciones. Con ayuda de ella y otros softwares desarrollados por centros internacionales de
investigacion, se pueden llevar a cabo an alisis exhaustivos y rigurosos de datos obtenidos en experi-
mentos, as como las simulaciones virtuales de experimentos fsicos que permiten un estudio mayor
anticipado para nalmente ejecutar el experimento real.
El presente curso tiene como misi on lograr que los estudiantes de fsica aprendan programaci on
orientada al an alisis de datos y simulacion en experimentos fsicos. Cualquier fsico, sea te orico o
experimental (aun cuando el experimental en mayor medida), debe conocer como abordar estas si-
tuaciones para as poder comprender como se lleva a cabo todo el proceso de investigacion de un
determinado tema. Cabe recordar al alumno que este es un curso orientado a fsicos, por lo cual
no se encontrar a con una denici on profunda y tediosa de conceptos de inform atica, si no mas bien
un estudio de las herramientas que la informatica tiene a disposicion de un cientco, por medio de
aplicaciones reales a la fsica, sobretodo a la fsica de partculas.
La estructura de este curso consistir a en una introduccion a la programacion en el lenguaje c++, por
ser el lenguaje mundialmente ocupado en los laboratorios de investigaci on. Tambien se realizar a una
revisi on de elementos de probabilidad y estadstica orientados a procesos fsicos. Dirigiremos nuestra
atenci on al uso de dos software ocupados mundialmente en fsica de partculas, desarrollados por el
CERN, que requieren un conocimiento de c++ : Root y Geant4. El primero es un programa que nos
permitir a analizar y almacenar datos de experimentos con ayuda de herramientas estadsticas. El se-
gundo es otro programa que nos permitir a realizar simulaciones del comportamiento de las partculas
sometidas a diversos procesos fsicos como movimiento en campos electromagneticos o colisiones con
otras partculas, con el n de identicar todos los sub-procesos que se producen en estos eventos, asi
como obtener valores de las magnitudes fsicas involucradas. Es importante notar que ambos progra-
mas, al unirlos en el proceso de experimentaci on, son un arma potente de investigaci on. Anexo a esto
se estudiar an algunos fundamentos b asicos de fsica de partculas y las implicaciones que debemos
3
4
considerar a la hora de realizar los analisis respectivos.

Ambos programas se descargan en las paginas
que aparecen al nal del curso. Ademas, debido a que est an desarrollados para trabajar con mayor
comodidad en el sistema operativo Linux, se requiere que el estudiante tenga instalado en su compu-
tador cualquier variante de este sistema (Ubuntu, Fedora, etc).
Finalmente se recuerda al alumno que aprender programacion no es mas que un trabajo de ensuciarse
las manos. Se debe aprender todo lo relativo a ello, pero de nada sirve si no se aplica personalmente.
Por lo tanto, se llama a realizar un trabajo personal y comprometido por medio de tareas y ejercicios
propios.
Conociendo Linux
Unix es uno de los sistemas operativos m as populares del mundo debido a su extenso soporte y
distribuci on. Muchos hackers consideran que es el autentico y unico sistema operativo.
Linux es una versi on del n ucleo de Unix, aun cuando no comparten ninguna lnea de c odigo identica
entre ambos. El desarrollo de GNU/Linux parte de un grupo en expansi on de hackers que quisieron
hacer un sistema operativo libre con sus propias manos, concluyendo en un SO con variadas herra-
mientas potentes.
En seguida comprenderemos lo necesario para trabajar con Linux de buena forma. Primero que nada,
comprenderemos como instalarlo y una vez instalado, como ingresar y desenvolverse en el a traves de
la terminal.
Instalaci on
Ahora usted debe instalar Linux en su computador mediante alg un metodo que usted considere
conveniente.
Ingreso al sistema
Luego de crear el usuario, no debemos mas que ingresar al sistema con el nombre de usuario y la
contrasea.
Operando en la terminal
La terminal es la interfaz entre el sistema operativo y nosotros. Con ciertos comandos que debemos
escribir en la terminal, podemos desenvolvernos por Linux de manera r apida e incluso modicar el
mismo sistema operativo (esto es, porque Linux es un SO libre). Para ir a la terminal, debemos ir a
inicio y desde ah buscar la terminal.
Una vez en la terminal, estaremos situados virtualmente sobre la carpeta personal de nuestro usuario.

Este directorio contiene todos los archivos del usuario en el cual estamos. Mas atr as del directorio
, se sit uan varios otros que contienen archivos necesarios para el sistema operativo. Un mapa de
directorios de Linux se observa a continuaci on; los directorios jane, will y zeb son los usuarios y work
y play son las carpetas que a creado el usuario will.
5
6
Siguiendo este mapa, la direcci on de la carpeta personal del usuario jane sera:
/home/jane
Cabe destacar que el usuario administrador (algo as como el usuario padre, quien puede modi-
car varias caractersticas que un usuario normal no puede) se denomina root y para poder acceder a
operar como el, debemos escribir en la terminal el comando sudo (super user do) seguido de la accion
a realizar (como instalar programas por ejemplo).

Esto nos pedir a el password del usuario en el que
estamos y podremos trabajar como asministrador
Una vez situados en el sistema de archivos del computador, podemos navegar por las distintas carpe-
tas, ejecutar programas, mover archivos, borrar archivos, etc. A continuaci on veamos algunos coman-
dos basicos sucientes para poder desenvolverse con tranquilidad por Linux. Si queremos manipular
un archivo en el directorio en el que estemos, solo escribiremos su numbre; si no estamos en el direc-
torio, debemos escribir la ruta completa.
Comando Funcion
cd [directorio] Abre un directorio
cd .. Retrocede un directorio
cd . Permanece en el mismo directorio (observemos que ene sta caso el punto representa el directorio actual)
cd Nos sit ua en el directorio home
ls Muestra el contenido del directorio en el cual estamos situados
la Muestra el contenido del directorio con los archivos ocultos incluidos en el cual estamos situados
cat [archivo/ruta del archivo] Muestra el contenido del archivo
mkdir [directorio nuevo] Creamos un nuevo directorio en el directorio donde estamos situados
cp [archivo/ruta del archivo] [directorio objetivo] Copia el archivo que hemos descrito al directorio objetivo
mv [archivo/ruta del archivo] [directorio objetivo] Mueve el archivo que hemos descrito al directorio objetivo
rm [Directorio/archivo/ruta del archivo] Elimina el directorio o el archivo especicado
man [comando] Muestra una descripci on del comando
[nombre-programa] [archivo/ruta del archivo] Ejecuta el archivo con el programa indicado
7
Instalaci on y desinstalaci on de programas y paquetes desde
la consola
Instalaci on con APT
APT (Advanced Packaging Tool) es el gestor de paquetes (paquetes de programas, los progra-
mas pueden ser empaquetados) usado por Linux Debian. Para ejecutar APT, usaremos la interfaz (o
comando) aptitude o apt-get. Para otros usos de APT relacionados con la memoria cache, usaremos
apt-cache, pero en este curso no interesa. Si lo ejecutamos, veremos una interfaz donde podemos
revisar el estado de distintos paquetes en nuestro sistema. Aptitude obtiene la lista de paquetes dis-
ponibles del repositorio de Linux, que es un conjunto de direcciones de Internet o locales donde estan,
tanto los listados de paquetes disponibles, como los propios paquetes. El programa aptitude se usa en
modo lnea de comando desde un terminal, en el que debe tener la condicin de superusuario (root).
Con aptitude podemos realizar varias acciones desde la terminal:
1. aptitude update: Actualiza la lista de paquetes (Es lo primero que debemos hacer antes de usar
aptitude).
2. aptitude install [paquete]: Instala el paquete determinado.
3. aptitude reinstall [paquete]: Actualiza o reinstala un paquete (que puede estar daado).
4. aptitude -d install [paquete] Descarga un paquete determinado pero no lo instala.
5. aptitude upgrade: Actualiza todos los paquetes de una sola vez (tratar de no usar)
6. aptitude remove [paquete]: Desinstala un paquete.
7. aptitude purge [paquete]: Desinstala un paquete con sus archivos de conguraci on.
Instalaci on desde las fuentes
Hay veces que para instalar un programa, debemos descargar los cheros fuentes de este que est an
comprimidos en archivos .tgz (o tar.gz) y .bz2 . Si es que no encontramos en las fuentes alg un archivo
readme o install, el proceso de instalacion se reduce a 4 pasos:
1. Descomprimir las fuentes mediante el comando tar:
tar zxvf nombre_archivo.tgz
tar zxvf nombre_archivo.tar.gz
tar jxvf nombre_archivo.bz2
Ahora debemos posicionarnos en la carpeta donde hemos descomprimido las fuentes:
cd /ruta
8
2. Tecleamos:
./configure
Aca se chequean los programas necesarios para la compilacion. Si no hay problema, podemos
pasar al siguiente paso. Si necesitamos algunos paquetes, debemos obtenerlos con APT.
3. Tecleamos:
make
Compila las fuentes y crea otros archivos necesarios.
4. Tecleamos:
make install
Instalamos el programa.
Con esto, ahora usted puede instalar el programa Root del cern, descargando los cheros
fuentes desde la p agina http://root.cern.ch.
Algoritmos
Un algoritmo es un metodo paso a paso para resolver un problema.
Un ejemplo es un algoritmo para saber si un n umero es primo o no primo como el que sigue:
Cualquier n umero es primo si solo es divisible entre si mismo y la unidad.
Por lo tanto, para saber si un n umero N es primo o no, bastara con dividirlo por todos los nmeros
entre 2 y N-1, y si ninguna divisin es exacta, entonces el nmero N es primo.
Pero hay algunas mejoras que podemos aplicar:
La primera es que no es necesario probar con todos los n umeros entre 2 y N-1, ya que podemos dar
por supuesto que si N no es divisible entre 2, tampoco lo sera para ning un otro n umero par: 4, 6, 8...,
por lo tanto, despus de probar con 2 pasaremos al 3, y despues podemos probar slo con los impares.
La segunda es que tampoco es necesario llegar hasta N-1, en realidad, solo necesitamos llegar hasta
el valor entero mas cercano a la raz cuadrada de N.
Esto es as porque estamos probando con todos los n umeros menores que N uno a uno. Supongamos
que vamos a probar con un n umero M mayor que la raz cuadrada de N. Para que M pudiera ser un
divisor de N debera existir un nmero X que multiplicado por M fuese igual a N.
N = MxX
El caso extremo, es aquel en el que M fuese exactamente la raz cuadrada de N. En ese caso, el valor
de X sera exactamente M, ya que ese es el valor de la raz cuadrada de N:
N = M
2
= MxM
Pero en el caso de que M fuese mayor que la raz cuadrada de N, entonces el valor de X debera ser
menor que la raz cuadrada de N. Y el caso es que ya hemos probado con todos los nmeros menores
que la raz cuadrada de N, y ninguno es un divisor de N.
Por lo tanto, ning un n umero M mayor que la raz cuadrada de N puede ser divisor de N si no existen
n umeros menores que la raz cuadrada de N que lo sean.
Los cientcos en computaci on denen s olo tres pasos necesarios en la construccion de un algorit-
mo. Estos son Secuencia, Desicion y Repeticion.
En la Secuencia, se da una seguidera de instrucciones de la forma:
9
10
do action 1
do action 2
...
do action n
En la Desici on, se prueba una concidicion y dependiendo de su veracidad, se realizan acciones de
forma:
if this condition is true:
Do a series of actions
else:
Do another series of actions
En la Repeticion, muchas veces deben repetirse las series de acciones. Esto se logra con los loops o
los bucles de la forma:
While a condition is true:
Do a series of actions
Debemos comprender estos tres pasos y podremos dise nar cualquier tipo de algoritmo
Pseudocodigos
El pseudoc odigo es un lenguaje creado para expresar algoritmos formalmente y de manera clara.
No es en si mismo un lenguaje de programacion, sino m as bien, un lenguaje formal (con reglas muy
extrictas), pero humano, que intenta evitar ambig uedades.
Un pseudocodigo para el algoritmo anterior podra ser:
Es N=1? -> N es primo, salir
Es N=2? -> N es primo, salir
Asignar a M el valor 2
mientras M <= raz cuadrada(N) hacer:
Es N divisible entre M? -> N no es primo, salir
Si M=2 entondes Asignar a M el valor 3
Si M distinto de 2 entonces Asignar a M el valor M+2
Fin del mientras
N es primo ->salir
Algoritmo de la burbuja
Para adentrarnos un poco mas en los algoritmos, veremos el que es mas sencillo probablemen-
te. El algoritmo de la burbuja es un algoritmo que permite ordenar una lista de valores seg un un
orden determinado. Consiste en ciclar repetidamente a traves de la lista, comparando elementos adya-
centes de dos en dos. Si un elemento es mayor que el que est a en la siguiente posicion se intercambian.
11
Vamos a ver un ejemplo. Esta es nuestra lista:
4 - 3 - 5 - 2 - 1
Tenemos 5 elementos. Es decir, TAM toma el valor 5. Comenzamos comparando el primero con
el segundo elemento. 4 es mayor que 3, as que intercambiamos. Ahora tenemos:
3 - 4 - 5 - 2 - 1
Ahora comparamos el segundo con el tercero: 4 es menor que 5, as que no hacemos nada. Con-
tinuamos con el tercero y el cuarto: 5 es mayor que 2. Intercambiamos y obtenemos:
3 - 4 - 2 - 5 - 1
Comparamos el cuarto y el quinto: 5 es mayor que 1. Intercambiamos nuevamente:
3 - 4 - 2 - 1 - 5
Repitiendo este proceso vamos obteniendo los siguientes resultados:
3 - 2 - 1 - 4 - 5
2 - 1 - 3 - 4 - 5
1 - 2 - 3 - 4 - 5
Practica: Escriba un pseudocodigo del algoritmo de la burbuja
Algoritmo de Euclides
El algoritmo de Euclides sirve para calcular el MCD (maximo com un divisor) de dos n umeros.
Aunque existen otros metodos mas sencillos de calcular el MCD de dos o mas n umeros, este metodo
tiene la caracterstica de ser muy f acil de programar.
El algoritmo de Euclides es el siguiente (en pseudo-cdigo):
Si a es igual a b entonces el MCD es a (o b)
(*)Sino:
Si a es mayor que b entonces a toma el valor de (a - b)
Sino b toma el valor de (b - a)
Verificar si a es igual a b:
12
Si es igual entonces el MCD es a ( b)
Sino regresar a (*)
Estos pseudocodigos son muy utiles para que los entendamos nosotros, pero el ordenador no los
entender a. En el captulo siguiente veremos como pasar nuestros pensamientos al lenguaje de maquina
mediante el uso de un lenguaje de programaci on.
Programaci on en C++
Es tiempo de adentrarnos en C++. C++ tiene un mont on de ventajas sobre otros lenguajes; uno
de los principales es que es un lenguaje orietado a objetos (POO). Veremos que signica esto mas
adelante. Aprenderemos primero a poder traspasar nuestro ordenamiento mental a un modo que sea
entendible para la m aquina y as lograr el procesamiento y an alisis de datos experimentales deseados.
Para programar en C++ , necesitamos principalmente 3 cosas:
1. Sistema Operativo (Linux para nuestro caso)
2. Editor de Texto (gedit, vim, emacs, anjuta, bluesh, etc)
3. Compilador de C++(en nuestro caso usaremos g++ que viene por defecto en nuestro SO)
Otros, como los enlazadores vienen contenidos en nuestro compilador g++ y los debuggers no son
necesarios. Veremos esto con mayor atenci on en lo que sigue el curso.
Analicemos algunos conceptos de programaci on necesarios para comprender mejor.
Obtencion de un programa ejecutable
El programa ejecutable, es el programa en s listo para realizar la accion para la cual fue creado. El
ordenador, de alguna forma u otra, llamara a este programa ejecutable para que este act ue. Antes de
empezar, deniremos algunos conceptos importantes de programaci on que nos ser an de gran utilidad
para comprender como producir un programa listo para ser ejecutado en C++ de manera correcta:
Ficheros fuente
Los programas en C++ se escriben en un editor de textos del mismo modo que cualquier texto
corriente. Los cheros que contiene programas en C++ en forma de texto se conocen como cheros
fuente, y el texto del programa que contiene se conoce como programa fuente. Podemos usar variados
editores de textos entre otros como gedit, vim, emacs, anjuta o geany.
Interpretes y compiladores
C++ es un lenguaje compilado, y no interpretado. Esta diferencia es muy importante, ya que
afecta mucho a muchos aspectos relacionados con la ejecucin del programa.
En un lenguaje interpretado, el programa est a escrito en forma de texto; es el propio programa fuente.
Este programa fuente es procesado por un programa externo, el interprete, que traduce el programa,
13
14
instrucci on a instrucci on, al tiempo que lo ejecuta. En los lenguajes interpretados no existen progra-
mas ejecutables directamente por el ordenador. El intrprete traduce, en tiempo real, cada lnea del
programa fuente, cada vez que se quiere ejecutar el programa.
El los lenguajes compilados el proceso de traducci on solo se hace una vez. El programa compila-
dor toma como entrada el cdigo fuente del programa, y da como salida un chero que puede ser
ejecutado por el ordenador directamente. Una vez compilado, el programa ejecutable es aut onomo, y
ya no es necesario disponer del programa original ni del compilador para ejecutarlo.
Los lenguajes interpretados son f acilmente modicables, ya que necesitamos tener el el c odigo fuente
disponible en el ordenador. En los compilados, estos cheros no son necesarios, una vez compilados.
Los lenguajes interpretados necesitan un programa externo, llamado interprete o a veces maquina
virtual, o framework. Este programa actua como intermediario entre el fuente y el sistema operativo.
En los compilados ese papel lo desempea el compilador, pero al contrario que con el interprete, una
vez ha hecho su trabajo, no es necesario que este presente para ejecutar el programa.
Estas dos caractersticas, l ogicamente, hacen que los programas compilados requieran menos espacio
de memoria que los interpretados (si contamos el espacio usado por el interprete), y en general, los
compilados son mas rapidos, ya que s olo se compilan una vez, y el tiempo dedicado a esa tarea no se
suma al de ejecucin.
Entre los lenguajes interpretados estan: BASIC (Cdigo de instrucciones de propsito general para
principiantes), Java, PHP, muchos lenguajes de script, etc. Entre los lenguajes compilados est an: C,
C++, Pascal.
Ficheros objeto y compiladores
En los lenguajes compilados, los programas fuente no pueden ejecutarse. Son cheros de texto,
pensados para que los comprendan los seres humanos, pero incomprensibles para los ordenadores.
Para conseguir un programa ejecutable hay que seguir algunos pasos. El primero es compilar o traducir
el programa fuente a su cdigo objeto equivalente. Este es el trabajo que hacen los compiladores de C
y C++. Consiste en obtener un chero equivalente a nuestro programa fuente comprensible para el
ordenador, este chero se conoce como chero objeto, y su contenido como cdigo objeto.
El cdigo objeto no suele tener ningn signicado para los seres humanos. Adems es diferente para cada
ordenador y para cada sistema operativo. Por lo tanto existen diferentes compiladores para diferentes
sistemas operativos y para cada tipo de ordenador.
Libreras o bibliotecas
Junto con los compiladores de C++, se incluyen ciertos cheros llamados bibliotecas. Las bibliote-
cas contienen el c odigo objeto de muchos programas que permiten hacer cosas comunes, como leer el
teclado, escribir en la pantalla, manejar n umeros, realizar funciones matematicas, etc. Las bibliotecas
est an clasicadas por el tipo de trabajos que hacen, hay bibliotecas de entrada y salida, matem aticas,
de manejo de memoria, de manejo de textos, etc.
15
Hay un conjunto de bibliotecas muy especiales, que se incluyen con todos los compiladores de
C++. Son las libreras ANSI o est andar.
Ficheros ejecutables y enlazadores
Cuando obtenemos el chero objeto, a un no hemos terminado el proceso. El chero objeto, a pesar
de ser comprensible para el ordenador, no puede ser ejecutado. Hay varias razones para eso:
1. Nuestros programas usar an, en general, funciones que estar an incluidas en bibliotecas externas,
ya sean ANSI o no. Es necesario combinar nuestro chero objeto con esas bibliotecas para
obtener un ejecutable.
2. Muy a menudo, nuestros programas estaran compuestos por varios cheros fuente, y de cada
uno de ellos se obtendr a un chero objeto. Es necesario unir todos los cheros objeto, m as las
bibliotecas en un unico chero ejecutable.
3. No siempre obtendremos un chero ejecutable para el c odigo que escribimos, a veces querremos
crear cheros de biblioteca, y en ese caso el proceso ser a diferente.
Existe un programa que hace todas estas cosas, se trata del linker, o enlazador. El enlazador toma
todos los cheros objeto que componen nuestro programa, los combina con los cheros de biblioteca
que sean necesarios y crea un chero ejecutable. Sin embargo, en nuestro caso no debemos preocu-
parnos pues el compilador que usaremos g++ tiene el enlazador contenido en el y lo ignoraremos.
Errores
Por supuesto, somos humanos, y por lo tanto nos equivocamos. Los errores de programacion pue-
den clasicarse en varios tipos, dependiendo de la fase en que se presenten.
Errores de sintaxis: son errores en el programa fuente. Pueden deberse a palabras reservadas mal
escritas, expresiones err oneas o incompletas, variables que no existen, etc. Los errores de sintaxis se
detectan en la fase de compilaci on. El compilador, adem as de generar el c odigo objeto, nos dara una
lista de errores de sintaxis. De hecho nos dara slo una cosa o la otra, ya que si hay errores no es
posible generar un c odigo objeto.
Avisos: adem as de errores, el compilador puede dar tambien avisos (warnings). Los avisos son errores,
pero no lo sucientemente graves como para impedir la generaci on del codigo objeto. No obstante,
es importante corregir estos errores, ya que ante un aviso el compilador tiene que tomar decisiones,
y estas no tienen por que coincidir con lo que nosotros pretendemos hacer, ya que se basan en las
directivas que los creadores del compilador decidieron durante la creacin del compilador.
Errores de enlazado: el programa enlazador tambien puede encontrar errores. Normalmente se re-
eren a funciones que no estan denidas en ninguno de los cheros objetos ni en las bibliotecas.
Puede que hayamos olvidado incluir alguna biblioteca, o alg un chero objeto, o puede que hayamos
olvidado denir alguna funcin o variable, o lo hayamos hecho mal.
16
Errores de ejecucion: incluso despues de obtener un chero ejecutable, es posible que se produz-
can errores. En el caso de los errores de ejecuci on normalmente no obtendremos mensajes de error,
sino que simplemente el programa terminar a bruscamente. Estos errores son mas difciles de detec-
tar y corregir. Existen programas auxiliares para buscar estos errores, son los llamados depuradores
(debuggers). Estos programas permiten detener la ejecucion de nuestros programas, inspeccionar va-
riables y ejecutar nuestro programa paso a paso (instrucci on a instruccion). Esto resulta util para
detectar excepciones, errores sutiles, y fallos que se presentan dependiendo de circunstancias distintas.
Errores de dise no: nalmente los errores mas difciles de corregir y prevenir. Si nos hemos equi-
vocado al dise nar nuestro algoritmo, no habra ning un programa que nos pueda ayudar a corregir los
nuestros. Contra estos errores s olo cabe practicar y pensar.
Primera practica
Para poder ver cada uno de estos conceptos denidos en accion, y empezar a comprender ciertas
caractersticas de programaci on en c++, escribiremos en nuestro editor de texto un programa simple,
que simplemente devuelve por pantalla la frase El electron cumple el principio de exclusion de Pauli.
#include <iostream>
int main(){
std::cout<<"El electron cumple el principio de exclusion de Pauli"<<std::endl;
}
El chero fuente debe ser guardado con la extensi on .c, por ejemplo programa.c. Luego de guar-
darlo, procederemos a efectuar el proceso de compilacion y luego el de ejecucion.
Haciendo un analisis r apido de nuestro programa, podemos ver que en la primera lnea aparece
el comando #include.

Este comando incluye en nuestro programa una librera con el nombre especi-
cado, que en este caso es iostream. Dicha librera contiene los comandos necesarios para mostrar y
recibir informaci on en pantalla (cout, cin, endl, etc.).
Luego nos damos cuenta que aparece la lnea int main().

Este c odigo aparece en todos los progra-
mas de C++ y es la funcion de entrada para que el compilador pueda reconocer que el programa
ha iniciado.

Estos comandos desde luego, seran analizados en mayor profundidad al avanzar este curso.
Para compilarlo debemos ir a una terminal en Linux. Debemos luego situarnos en la carpeta en
donde este nuestro chero fuente, y ahi efectuar el siguiente comando:
g++ [nombre del fichero fuente] -o [nombre del fichero ejecutable]
En este proceso el ordenador toma el archivo con el nombre del chero fuente especicado, lo com-
pila y lo enlaza al mismo tiempo (esto es una caracterstica que posee el compilador) y produce un
chero ejecutable con el nombre que nosotros queramos. Si no especicamos el nombre, producira por
defecto el archivo a.out, sin embargo, se recomienda siempre especicar un nombre propio. Si existen
errores, el compilador los arrojara en la terminal y no producira el archivo.
17
Luego, para ver en acci on nuestro programa debemos escribir en la terminal:
./[nombre del fichero ejecutable]

Esto ejecuta nuestro programa y veremos como ac

tua automaticamente. Veelo tu mismo.


Palabras reservadas
En C++ existen algunas palabras reservadas que no se pueden ocupar con libertad en el desarrollo
de un programa.

Estas palabras se ocupan solamente para lo que estan creadas y con ellas no podemos
nombrar nuevas variables. Algunas de estas palabras son los tipos de variables (char,int,...), los
comienzos de ciclos o loops (for,while,...) entre otras. Recomendamos revisar la red para ver un
listado completo de esas palabras.
Tipos de variables
Una variable es una entidad cuyo valor puede cambiar a lo largo de la ejecuci on de un programa.
Una variable ocupa un espacio de memoria reservado en el ordenador para contener sus valores du-
rante la ejecuci on de un programa. Cada variable debe pertenecer a un tipo determinado, y ese tipo
determina, por una parte, el tama no del espacio de memoria ocupado por la variable, y por otra, el
modo en que se manipulara esa memoria por el ordenador.
Todas las variables se declaran anteponiendo el tipo de esta a el o los nombres que designaremos
para nuestra(s) variable(s). Por ejemplo:
int numeroleptonico;
Designa una variable tipo int (entero) de nombre numeroleptonico. En otro ejemplo:
float energia_cinetica, momentum, masa;
Se designan designan tres variables de tipo oat (coma otante).
Tipo char
Es el tipo basico alfanumerico, es decir que puede contener un car acter, un dgito numerico o un
signo de puntuaci on. Desde el punto de vista del ordenador, todos esos valores son caracteres. Este
tipo de variables es apto para almacenar n umeros pequeos, como los dedos que tiene una persona, o
letras, como la inicial de mi nombre de pila.
Tipo int
Este tipo de variables es util para almacenar n umeros relativamente grandes, pero sin decimales,
por ejemplo el nivel de energa de un electron en un atomo o el n umero de partculas producidas en
una determinada colision.
18
Tipo oat
Las variables de este tipo almacenan n umeros en formato de coma otante, esto es, contienen un
valor de mantisa y otro de exponente, que, para entendernos, codican n meros con decimales. Estas
variables son aptas para variables de tipo real, como por ejemplo la temperatura. O para n umeros
muy grandes, como la energa en reposo de un planeta completo.
El fuerte de estos n umeros no es la precision, sino el orden de magnitud, es decir lo grande o peque no
que es el n umero que codica. Los formatos en coma otante sacrican precision en favor de tama no.
Sin embargo el ejemplo si funcionara con n umeros m as pequeos. Esto hace que las variables de tipo
oat no sean muy adecuadas para todos los casos, como veremos mas adelante.
Tipo bool
Las variables de este tipo s olo pueden tomar dos valores true (verdadero) o false (falso). Sirven
para evaluar expresiones lgicas. Este tipo de variables se puede usar para almacenar respuestas, por
ejemplo: Esta vivo el gato de la caja?. O para almacenar informaciones que solo pueden tomar dos
valores, por ejemplo El spin del electr on es
1
2
o
1
2
?.
Tipo double
Las variables de este tipo almacenan n umeros en formato de coma otante, mantisa y exponente,
al igual que oat, pero usan una precisi on mayor, a costa de usar ms memoria, claro. Son aptos
para variables de tipo real. Usaremos estas variables cuando trabajemos con n umeros grandes, pero
tambien necesitemos gran precisi on. El mayor espacio para almacenar el n umero se usa tanto para
ampliar el rango de la mantisa como el del exponente, de modo que no solo se gana en precisi on, sino
tambin en tamao.
Tipo void
Void es un tipo especial que indica la ausencia de tipo. Se usa para indicar el tipo del valor de
retorno en funciones que no devuelven ningn valor, y tambin para indicar la ausencia de parmetros
en funciones que no los requieren (es opcional en C++).
Operadores basicos
Los operadores son elementos que disparan ciertos c alculos cuando son aplicados a variables o a
otros objetos en una expresi on.
Operadores aritmeticos
1. Unitarios: Asignan valores positivos o negativos a la expresi on a la que se aplican. Se escriben:
19
+ <expresion>
- <expresion>
2. Binarios: Existen varios. +, -, *y /, tienen un comportamiento analogo en cuanto a los
operandos, ya que admiten tanto expresiones enteras, como en coma otante:
<expresion> + <expresion>
<expresion> - <expresion>
<expresion> * <expresion>
<expresion> / <expresion>
Otro operador binario es el de mdulo %, que devuelve el resto de la divisi on entera del primer
operando entre el segundo. Por esta raz on no puede ser aplicado a operandos en coma otante:
<expresion> % <expresion>
Por ultimo otros dos operadores unitarios. Se trata de operadores un tanto especiales, ya que s olo
pueden trabajar sobre variables, pues implican una asignaci on. Se trata de los operadores ++y
. El primero incrementa el valor del operando y el segundo lo decrementa, ambos en una unidad.
Existen dos modalidades, dependiendo de que se use el operador en la forma de prejo o de sujo.
Sintaxis:
<variable> ++ (post-incremento)
++ <variable> (pre-incremento)
<variable>-- (post-decremento)
-- <variable> (pre-decremento)
En su forma de prejo, el operador es aplicado antes de que se eval ue el resto de la expresi on; en la
forma de sujo, se aplica despues de que se eval ue el resto de la expresi on.
Operadores de Asignacion
Existen varios operadores de asignaci on, el m as evidente y el m as usado es el =, pero en C++
este no es el unico que existe. La sintaxis es:
<variable> <operador de asignacin> <expresin>
Operadores de comparacion
Comparan dos operandos arrojando un valor booleano como resultado:
<expresion> == <expresion>
<expresion> != <expresion>
<expresion> > <expresion>
<expresion> < <expresion>
<expresion> <= <expresion>
<expresion> >= <expresion>
Arrojara true si el resultado es verdadero y false si no lo es.
20
Operadores logicos
Los operadores &&, || y ! relacionan expresiones logicas, dando como salida a su vez nuevas
expresiones logicas.
El operador && equivale al AND o Y; devuelve true solo si los dos operandos true o lo que es
equivalente, distintas de cero. En cualquier otro caso el resultado es false.
El operador || equivale al OR u O inclusivo; devuelve true si cualquiera de las expresiones evaluadas
es true, o distinta de cero, en caso contrario devuelve false.
El operador ! es equivalente al NOT, o NO, y devuelve true cuando la expresi on evaluada es false o
cero, en caso contrario devuelve false.
Operador de preprocesador
El operador #sirve para dar ordenes o directivas al compilador. El preprocesador es un programa
auxiliar, que forma parte del compilador, y que procesa el chero fuente antes de que sea compila-
do. En realidad se limita a seguir las ordenes expresadas en forma de directivas del preprocesador,
modicando el programa fuente antes de que sea compilado.
Directiva Dene
La directiva dene, sirve para denir macros. Cada macro es una especie de f ormula para la
sustituci on de texto dentro del chero fuente, y puede usar, opcionalmente par ametros.
#define <identificador_de_macro> <secuencia>
El preprocesador sustituir a cada ocurrencia del < identificador de macro > en el chero fuente, por
la < secuencia >, (aunque con algunas excepciones). Cada sustituci on se denomina expansion de la
macro, y la secuencia se suele conocer como cuerpo de la macro. Por ejemplo:
#define suma(a,b) ((a)+(b))
Reemplazar a todos los suma(a,b) por ((a)+(b))
Directiva Include
La directiva include, como ya hemos visto, sirve para insertar cheros externos dentro de nuestro
chero de codigo fuente. Estos cheros son conocidos como cheros incluidos, cheros de cabecera o
headers:
#include <nombre de fichero cabecera>
#include "nombre de fichero de cabecera"
El preprocesador elimina la lnea include y la sustituye por el chero especicado.
La diferencia entre escribir el nombre del chero como <nombre de chero cabecera> o nombre
de chero de cabecera, esta en el algoritmo usado para encontrar los cheros a incluir. En el primer
caso el preprocesador buscar a en los directorios ncludedenidos en el compilador. En el segundo, se
21
buscar a primero en el directorio actual, es decir, en el que se encuentre el chero fuente, si el chero
no existe en ese directorio, se trabajar a como el primer caso. Si se proporciona el camino como parte
del nombre de chero, s olo se buscar a es ese directorio.
Funciones
Las funciones son un conjunto de instrucciones que realizan una tarea especca. En general toman
ciertos valores de entrada, llamados par ametros y proporcionan un valor de salida o valor de retorno;
aunque en C++, tanto unos como el otro son opcionales, y pueden no existir. Todos los programas
C++ contienen, como mnimo, una funcion.
Prototipos
En C++ es obligatorio usar prototipos. Un prototipo es una declaraci on de una funci on. Consiste
en una presentaci on de la funci on, exactamente con la misma estructura que la denicion, pero sin
cuerpo y terminada con un ;. La estructura de un prototipo es:
[extern|static] <tipo_valor_retorno> [<modificadores>] <identificador>(<lista_parmetros>);
Extern y Static son caractersticas de la funcion que no son necesarias escribirlas. El identicador de
la funcion es el nombre de la misma, el cual debe ser simple. Por ejemplo:
float Energia(p,m);
Es el prototipo de una funcion que devuelve un valor otante de energa tomando como valores de
entrada p y m.
Denici on de funciones
Hemos visto la declaracion de funciones de parte de los prototipos, pero no hemos visto como se
denen las instrucciones de la funcion. La sintaxis es:
[extern|static] <tipo_valor_retorno> [modificadores] <identificador>(<lista_parmetros>)
{
[sentencias]
}
La denici on de la funci on se hace mas adelante o m as abajo, seg un se mire, es decir, se hace despues
que el prototipo. Lo habitual es hacerlo despues de la funci on main.
La lista de par ametros contiene todas las variables que ocupar a la funci on separadas por comas:
int Suma(int a, int b);
Si es que queremos jar un parametro por defecto; esto es, que si no asignamos dicho par ametro tome
un valor preestablecido, debemos escribir:
int Suma(int a, int b=2);
22
En este caso, si no pasamos un segundo argumento, b tomar a el valor 2
Una funci on muy especial es la funci on main, de la que ya hablamos anteriormente. Se trata de
la funcion de entrada, y debe existir siempre, ya ser a la que tome el control cuando se ejecute el
programa. Existen reglas para el uso de los valores de retorno y de los par ametros de la funci on main,
pero de momento la usaremos como int main() o int main(void), con un entero como valor de retorno
y sin parametros de entrada. El valor de retorno indicar a si el programa ha terminado sin novedad
ni errores retornando cero, cualquier otro valor de retorno indicar a un cdigo de error.
int main(){
[sentencias]
...
return 0
}
Estructura de un programa
La estructura de un programa, seg un lo que hemos visto, quedara as:
[directivas del pre-procesador: includes y defines]
[declaracin de variables globales]
[prototipos de funciones]
[declaraciones de clases]
funcion main
[definiciones de funciones]
[definiciones de clases]
Tambien se puede omitir el prototipo si se hace la denici on antes de cualquier llamada a la funci on,
es decir, en la zona de declaraci on de prototipos. Esto se puede hacer siempre, sin embargo no es muy
recomendable como veremos a lo largo del curso.
Sentencias
El elemento que nos falta para empezar a escribir programas que funcionen son las sentencias.
Existen sentencias de varios tipos, que nos permitir an enfrentarnos a todas las situaciones posibles
en programaci on. Estos tipos son:
1. Bloques
2. Expresiones
3. Bucles
4. Saltos
5. Seleccion
23
Bloques
Una sentencia compuesta o un bloque es un conjunto de sentencias, que puede estar vaca, ence-
rrada entre llaves . Sintacticamente, un bloque se considera como una unica sentencia.
Expresiones
Una expresi on seguida de un punto y coma (;), forma una sentencia de expresion. La forma en que
el compilador ejecuta una sentencia de este tipo evaluando la expresion. Cualquier efecto derivado de
esta evaluaci on se completar a antes de ejecutar la siguiente sentencia. Aca aparecen:
Llamadas a funcion
Esta es la manera de ejecutar las funciones que se denen en otras partes del programa o en el
exterior de este, ya sea una biblioteca est andar o particular. Consiste en el nombre de la funcion, una
lista de argumentos entre parentesis y un ;.
Por ejemplo:
Energia (p,m);

Esto ejecuta la funci on.


Asignacion
Las sentencias de asignaci on responden al siguiente esquema:
<variable> <operador de asignacion> <expresion>;
La expresion de la derecha es evaluada y el valor obtenido es asignado a la variable de la izquierda.
Por ejemplo:
p=134;
Nula
La sentencia nula consiste en un unico ;. Sirve para usarla en los casos en los que el compilador
espera que aparezca una sentencia, pero en realidad no pretendemos hacer nada. Veremos ejemplo de
esto cuando lleguemos a los bucles.
Bucles
Estos tipos de sentencias son el n ucleo de cualquier lenguaje de programacion, y estan presentes
en la mayor parte de ellos. Nos permiten realizar tareas repetitivas, y se usan en la resoluci on de la
mayor parte de los problemas.
24
Mientras
Es la sentencia de bucle m as sencilla, y sin embargo es tremendamente potente. En C++ se usa
la palabra reservada while (que signica mientras), y la sintaxis es la siguiente:
while (<condicion>) {
<sentencias>
}
Estos tipos de sentencias son el n ucleo de cualquier lenguaje de programacin, y estan presentes en la
mayor parte de ellos. Nos permiten realizar tareas repetitivas, y se usan en la resolucion de la mayor
parte de los problemas. Por ejemplo:
while (i<23){
i++;
}
Incrementar a el valor de i hasta que llegue a 23.
Hacer mientras
Esta sentencia va un paso m as all a que el while. La sintaxis es la siguiente:
do {<sentencias>} while(<condicion>);
La sentencia es ejecutada repetidamente mientras la condici on resulte verdadera. Si no se especica
condici on se asume que es true, y el bucle se ejecutara indenidamente.
A diferencia del bucle while, la evaluacion de la condici on se realiza despues de ejecutar la sentencia,
de modo que esta se ejecutar a al menos una vez. Por ejemplo:
do {
i++;
}
while (i < 23);
En este bucle se incrementar a el valor de i hasta que valga 23.
Pero aunque la condici on sea falsa, por ejemplo, si i vale inicialmente 25, la sentencia i + +;, se
ejecuta primero, y despues se verica la condicion.
Para
Por ultimo el bucle para, que usa la palabra reservada for. Este tipo de bucle es el m as elaborado.
La sintaxis es:
for ( [<inicializacion>]; [<condicion>] ; [<incremento>] )
{<sentencia>;
}
25
La sentencia es ejecutada repetidamente mientras la condicion resulte verdadera, o expresado de otro
modo, hasta que la evaluaci on de la condicin resulte falsa.
Antes de la primera iteraci on se ejecutara la iniciacin del bucle, que puede ser una expresion o una
declaraci on. En este apartado se suelen iniciar las variables usadas en el bucle. Estas variables tambien
pueden ser declaradas en este punto, pero en ese caso tendr an validez ( ambito) solo dentro del bucle
for.
Despues de cada iteraci on se ejecutar a el incremento de las variables del bucle. Este incremento
tambien es una sentencia de asignacion, y no tiene por que ser necesariamente un incremento.
En general, podemos considerar que la parte de inicializaci on establece las condiciones iniciales del
bucle, la parte de la condici on establece la condicion de salida, y la parte del incremento, modica las
condiciones iniciales para establecer las de la siguiente iteracion del bucle, o para alcanzar la condicion
de salida.
Todas las expresiones son opcionales, y si no se especica la condicion se asume que es verdadera.
Ejemplos:
for(int i = 0; i < 100; i = i + 1);
for(int i = 100; i < 0; i = i - 1);
Equivalencia while-for
Un bucle for lo podemos simular mediante un bucle while de la forma:
[<inicializacin>];
while([<condicin>]) {
<sentencia>
[<incremento>]
}

Esto hace que los bucles for no sean totalmente necesarios, pero simplican bastante la programaci on.
Seleccion
Si, si no
Permite la ejecucion condicional de una sentencia solo si la condici on es verdadera,de la forma:
if (<condicion>) <sentencia1>
[else <sentencia2>]
Si la condicin es verdadera se ejecutara la sentencia1, si es falsa, (y si existe la parte del else), se
ejecutar a la sentencia2.
La cla usula else es opcional, y si se usa, no pueden insertarse sentencias entre la sentencia1 y el else.
26
Switch
Esta sentencia es una generalizaci on de las sentencias if...else. En el caso de las sentencias if,
la expresi on que se eval ua como condicin es booleana, lo que quiere decir que solo hay dos valores
posibles, y por lo tanto, s olo se puede elegir entre dos sentencias a ejecutar.
En el caso de la sentencia switch, la expresi on a evaluar ser a entera, por lo tanto, el n umero de
opciones es mucho mayor, y en consecuencia, tambien es mayor el n umero de diferentes sentencias
que se pueden ejecutar.
switch (<expresin entera>)
{
[case <expresin_constante1>: [<sentencias1>]]
[case <expresin_constante2>: [<sentencias2>]]
...
[case <expresin_constanten>: [<sentenciasn>]]
[default : [<sentencia>]]
}
Si la expresion entera no es igual a ninguna de las expresiones constantes que denimos, entonces se
har a lo que diga default. Veamos un ejemplo:
bool EsVocal;
char letra;
...
switch(letra)
{
case a:
case e:
case i:
case o:
case u:
EsVocal = true;
break;
default:
EsVocal = false;
}
En este caso, dependiendo del valor de letra, se tomaran diferentes acciones. La etiqueta break la
veremos m as adelante.
Salto
Los programas C++ se ejecutan secuencialmente, pero existen formas de romper este orden se-
cuencial, mediante el uso de sentencias de salto, que veremos a continuaci on.
27
Ruptura
En general, una sentencia break transere la ejecuci on secuencial a la siguiente sentencia, aban-
donando aquella en que se ejecuta.
y = 0;
x = 0;
while(x < 1000)
{
if(y == 1000) break;
y++;
}
x = 1;
En este ejemplo el bucle no terminara nunca si no fuera por la lnea del break, ya que x no cambia.
Despues del break el programa continuara en la lnea x = 1.
Continue
El uso de esta sentencia dentro de un bucle ignora el resto del codigo de la iteracion actual, y
comienza con la siguiente, es decir, se transere la ejecucion a la evaluaci on de la condicion del bucle:
y = 0;
x = 0;
while(x < 1000)
{
x++;
if(y >= 100) continue;
y++;
}
En este ejemplo la lnea y++ slo se ejecutara mientras y sea menor que 100, en cualquier otro caso
el control pasa a la siguiente iteracion, con lo que la condicion del bucle volvera a evaluarse.
Retorno
Esta es la sentencia de salida de una funci on, cuando se ejecuta, se devuelve el control a la rutina
que llamo a la funci on. Ademas, se usa para especicar el valor de retorno de la funci on:
return <sentencia>
Por ejemplo:
int Paridad(int x)
{
if(x % 2) return 1;
return 0;
}
Devolvera 1 si x es par, si no lo es retornar a 0.
28

Ambitos
Llamamos ambito a la zona desde que cierto objeto es accesible. En C++ solemos referirnos a dos
tipos de ambitos: temporal y de acceso. As, el ambito temporal indica el intervalo de tiempo en el
que un objeto existe o es accesible. El ambito de acceso nos dice desde donde es accesible.
Las variables declaradas dentro de un bucle, ser an accesibles s olo desde el propio bucle, esto es,
tendr an un ambito local para el bucle. Esto es porque las variables se crean al inciar el bucle y se
destruyen cuando termina. Evidentemente, una variable que ha sido destruida no puede ser accedida,
por lo tanto, el ambito de acceso esta limitado por el ambito temporal.
Las variables declaradas dentro de una funcion, y recuerda que main tambin es una funci on, s olo
ser an accesibles para esa funcion, desde el punto en que se declaran hasta el nal. Esas variables son
variables locales o de ambito local de esa funci on.
Enmascaramiento
Generalmente no es posible, y no suele ser necesario, declarar dos variables con el mismo nombre,
pero hay condiciones bajo las cuales es posible hacerlo.
Por ejemplo, podemos declarar una variable global con un nombre determinado, y declarar otra
variable (del mismo tipo o de otro diferente) de forma local en una funci
on, usando el mismo nombre.
En ese caso decimos que la segunda declaracion (la local), enmascara a la primera (la global). Con
eso queremos decir que el acceso a la variable global est a bloqueado o enmascarado por la local, que
es a la unica que podemos acceder directamente. Por ejemplo:
int x;
int main() {
int x;
x = 10;
return 0;
}
En este programa, cuando asignamos 10 a x estamos accediendo a la version local de la variable x.
En la funci on main, la variable global x est a enmascarada, y no puede accederse a ella directamente.
Existe un metodo para acceder a una variable global enmascarada por una variable local. Se trata del
operador de ambito, que consiste en dos caracteres de dos puntos seguidos (::). Si hubieramos escrito:
int x;
int main() {
int x;
29
::x = 10;
return 0;
}
La variable denida afuera de main hubiese tomado el valor 10.
Elementos de comunicacion: cout y cin
Se trata de la salida estandar, cout y de la entrada est andar cin. Estos objetos nos permiten enviar
a la pantalla o leer desde el teclado cualquier variable o constante, incluidos literales. El uso es muy
simple:
#include <iostream>
using namespace std;
cout << <variable|constante> << <variable|constante>...;
cin >> <variable> >> <variable>...;
Las 2 primeras lneas son necesarias porque las declaraciones que permiten el uso de cout y cin est an
en una biblioteca externa. Con estos elementos ya podemos realizar algunos programas.
Primeros programas
1. Fermion y Boson: Un fermion es una partcula con spin fraccionario y un bos on una partcula
con spin entero. Escriba un programa que reciba desde el usuario el valor del spin y retorne si
la partcula con dicho spin es un fermion o un bos on.
2. Levi-Civita: En matem aticas, y en particular en c alculo tensorial, se dene el smbolo de
Levi-Civita, tambien llamado el smbolo de permutaci on o tensor de Levi-Civita, como sigue:
Escriba una funcion LeviCivita(int i, int j, int k) que reciba tres par ametros de entrada corres-
pondientes a i, j y k y retorne el valor correspondiente del tensor de acuerdo a los valores de
ellos (recuerde que los ndices no pueden tomar valores diferentes de 1,2 o 3).
3. Conguraci on electr onica: Escriba una funcion cong(int Z, int c) que reciba los par ametros
del n umero at omico y la carga de un i on o atomo, y retorne la conguracion electr onica, sin
tomar en cuenta las anomalas que se presentan en algunos casos. El formato de salida debe
ser, de tal forma que si la conguracion es:
1s
2
2s
2
2p
5
30
Arroje:
1s(2)2s(2)2p(5)
El programa debe aguantar hasta un elemento que contenga 35 electrones.
Castings
En determinadas ocaciones, necesitamos convertir un tipo de variable a otra explcitamente. Esto
se logra con los Castings. Un casting tiene la forma:
(<nombre de tipo>)<expresion>
<nombre de tipo>(<expresion>)
Por ejemplo supongamos que tenemos las variables oat a, int b y oat c. Por reglas del compilador,
la variable d=a+b+c ser a de tipo oat, pero si queremos que esta sea de tipo int, podemos hacer:
d=int(a+b+c);
O bien:
d=(int)(a+b+c);
Arreglos o Arrays
Los arrays permiten agrupar datos usando un unico identicador. Todos los elementos de un array
son del mismo tipo, y para acceder a cada elemento se usan ndices;
<tipo> <identificador>[<num_elemen>][<num_elemen>]...;
Desde el punto de vista del programador, un array es un conjunto de datos del mismo tipo a los que
se puede acceder individualmente mediante un ndice. Por ejemplo:
int vector[10];
El compilador obtendr a espacio de memoria suciente para almacenar 10 objetos de tipo int, y el
programa podr a acceder a cada uno de esos valores para leerlos o modicarlos. Para acceder a cada
uno de los valores se usa un ndice, que en este caso podr a tomar valores entre 0 y 9. Usando el valor
del ndice entre corchetes, por ejemplo: vector[0] o vector[4].
Cuando slo se usa un ndice se suele hablar de vectores, cuando se usan dos, de tablas (o matrices).
Los arrays de tres o m as dimensiones no suelen tener nombres propios, pero podemos generalizarlos
matem aticamente como tensores.
31
Inicializaci on
float R[10] = {2, 32, 4.6, 2, 1, 0.5, 3, 8, 0, 12};
float S[] = {2, 32, 4.6, 2, 1, 0.5, 3, 8, 0, 12};
int N[] = {1, 2, 3, 6};
int M[][3] = { 213, 32, 32, 32, 43, 32, 3, 43, 21};
char Mensaje[] = "Error de lectura";
char Saludo[] = {H, o, l, a, 0};
Estos son diferentes tipos de inicializar un array. Cuando se inicializan los arrays en la declaracion
no es obligatorio especicar el tamao para la primera dimensi on, como ocurre en los ejemplos de las
lneas 2, 3, 4, 5 y 6. En estos casos la dimensi on que queda indenida se calcula a partir del n umero
de elementos en la lista de valores iniciales. El compilador sabe contar y puede calcular el tama no
necesario de la dimensi on para contener el n umero de elementos especicados. En el caso 2, el n umero
de elementos es 10, ya que hay diez valores en la lista. En el caso 3, sera 4. En el caso 4, ser a 3, ya
que hay 9 valores, y la segunda dimension es 3: 9/3=3. Y en el caso 5, el n umero de elementos es 17,
16 caracteres m as el cero de n de cadena.
Cadenas de caracteres
Analizaremos un caso particular de arrays, las cuales son las cadenas de caracteres.U na cadena
en C++ es un conjunto de caracteres, o valores de tipo char, terminados con el caracter nulo, es
decir el valor numerico 0. Internamente, en el ordenador, se almacenan en posiciones consecutivas de
memoria. Este tipo de estructuras recibe un tratamiento muy especial, ya que es de gran utilidad y
su uso es continuo.
La manera de denir una cadena es la siguiente:
char <identificador> [<longitud mxima>];
Cuando se declara una cadena hay que tener en cuenta que tendremos que reservar una posicion
para almacenar el car acter nulo terminador, de modo que si queremos almacenar la cadena HOLA,
tendremos que declarar la cadena como:
char Saludo[5];
La asignacion directa solo est a permitida cuando se hace junto con la declaraci on.
El siguiente ejemplo producir a un error en el compilador, ya que una cadena denida de este modo
se considera una constante.
char Saludo[5];
Saludo = "HOLA"
La manera correcta de asignar una cadena es:
32
char Saludo[5];
Saludo[0] = H;
Saludo[1] = O;
Saludo[2] = L;
Saludo[3] = A;
Saludo[4] = 0;
O bien:
char Saludo[5] = "HOLA";
Practica:
Vectores: Escribir una funci on oat dot(oat vector[3]) que calcule el producto punto de un vector
pasado como array. Escriba otra funci on oat norm(oat vector[3]) que calcule su norma y una fun-
ci on distance(oat vector1[3], oat vector2[3]) que calcule la distancia entre dos vectores.
Transformacion de Lorentz: En relatividad especial, una transformaci on de Lorentz es la rela-
ci on entres las coordenadas espacio-temporales de un sistema de referencia S y las coordenadas de
otro S

que se mueve con velocidad constante V respecto al primero.


S(x, y, z, t)

S( x, y, z,

t)
Si un sistema se mueve con velocidad V en direcci on del eje x respecto a otro, entonces la relaci on
entre las coordenadas, si asumimos que en el instante inicial t = t

= 0 los origenes de ambos sistemas


coinciden, estan dadas por:
Donde c es la velocidad de la luz (300,000[km/s]) y las constantes y est an dadas por:
Escriba una funcion void LorentzT(oat vector[4],oat V) que arroje por pantalla todos los valores
de las coordenadas en un sistema que se mueve con velocidad V respecto del primero en el eje x.
Estructuras o Structs
Al contrario que los arrays, las estructuras nos permiten agrupar varios datos, que mantengan
alg un tipo de relaci on, aunque sean de distinto tipo, permitiendo manipularlos todos juntos, usando
33
un mismo identicador, o cada uno por separado. Las estructuras son llamadas tambien muy a menudo
registros, o en ingles records. Tienen muchos aspectos en com un con los registros usados en bases de
datos. Y siguiendo la misma analoga, cada objeto de una estructura se denomina a menudo campo,
o eld.
struct [<identificador>] {
[<tipo> <nombre_objeto>[,<nombre_objeto>,...]];
} [<objeto_estructura>[,<objeto_estructura>,...];
El identicador de la estructura es un nombre opcional para referirse a la estructura.
Los objetos de estructura son objetos declarados del tipo de la estructura, y su inclusi on tambien es
opcional. Sin bien, a un siendo ambos opcionales, al menos uno de estos elementos debe existir.
En el interior de una estructura, entre las llaves, se pueden denir todos los elementos que conside-
remos necesarios, del mismo modo que se declaran los objetos.
Las estructuras pueden referenciarse completas, usando su nombre, como hacemos con los objetos que
ya conocemos, y tambien se puede acceder a los elementos denidos en el interior de la estructura,
usando el operador de seleccion (.), un punto.
Una vez denida una estructura, es decir, si hemos especicado un nombre para ella, se puede usar
igual que cualquier otro tipo de C++. Esto signica que se pueden declarar m as objetos del tipo de
estructura en cualquier parte del programa. Para ello usaremos la forma normal de declaracion de
objetos, es decir:
[struct] <identificador> <objeto_estructura>
[,<objeto_estructura>...];
Por ejemplo:
struct particula{
float Carga;
float Masa;
float Spin;
} quarkUp;
Aqu denimos la estructura partcula y declaramos a quarkUp como un objeto de este tipo, Podemos
acceder por ejemplo a la carga del objeto quarkUp como:
quarkUp.Carga
C++, permite incluir funciones en el interior de las estructuras. Normalmente estas funciones tienen
la mision de manipular los datos incluidos en la estructura, y su uso esta muy relacionado con la
programaci on orientada a objetos.
Aunque esta caracterstica se usa casi exclusivamente con las clases, como veremos mas adelante,
tambien puede usarse en las estructuras. De hecho, en C++, las diferencias entre estructuras y clases
son muy tenues.
34
Dos funciones muy particulares son las de inicializaci on, o constructor, y el destructor. Veremos
con mas detalle estas funciones cuando asociemos las estructuras y los punteros.
El constructor es una funcion sin tipo de retorno y con el mismo nombre que la estructura. El
destructor tiene la misma forma, salvo que el nombre va precedido el smbolo -.
struct Sciencist{
char nombre;
char apellido;
int edad;
Sciencist(){nombre="Fulano", apellido="de Tal", edad=0}
} Sciencist1;
Si no usaramos un constructor, las caractersticas asociadas a Sciencist1 estaran indeterminados,
contendran la basuraque hubiese en la memoria asignada a estas estructuras durante la ejecuci on.
Con las estructuras este ser el caso mas habitual, ya que si necesitamos usar constructores para asig-
nar valores iniciales, sera mucho m as l ogico usar clases que estructuras.
Mencionar aqu, solo a ttulo de informaci on, que el constructor no tiene por que ser unico. Se
pueden denir varios constructores, pero veremos esto mucho mejor y con ms detalle cuando veamos
las clases. Podemos tambien jar nuevas funciones que se pueden aplicar a las clases:
struct Sciencist{
char nombre;
char apellido;
int edad;
Sciencist(){nombre="Fulano"; apellido="de Tal"; edad=0;}
ObtenerNombre(){ return nombre;}
Cumple(){ edad++;}
} Sciencist1;
En este caso, las funciones aplicadas a un objeto tipo Sciencist aumentaran la edad y nos entregaran
el nombre de la persona. Para aplicar estas funciones tambien ocupamos el (.).
Practica:
Fracciones: Denir una estructura fraccion que contenga el n umerador y el denominador y de-
nir una funci on para ella simplicar() que modique la fracci on a su irreductible. Puede ocupar el
metodo de Euclides para buscar MCD.
Ion: Denir una estructura ion que contenga el n umero at omico, el n umero masico y la carga de este.
Crear una funcion ionizar (int n) que aumente o disminuya la carga del ion segun n. Implementar la
funci on de conguraci on electronica hecha anteriormente a esta estructura.
35
Punteros
Los punteros proporcionan la mayor parte de la potencia al C++, y marcan la principal diferencia
con otros lenguajes de programacion. Creo que todos sabemos lo que es un puntero, fuera del ambito
de la programacion. Usamos punteros para se nalar cosas sobre las que queremos llamar la atenci on,
como marcar puntos en un mapa o detalles en una presentaci on en pantalla. A menudo, usamos el
dedo ndice para se nalar direcciones o lugares sobre los que estamos hablando o explicando algo.
Cuando un dedo no es suciente, podemos usar punteros. Antiguamente esos punteros eran una vara
de madera, pero actualmente se usan punteros laser, aunque la idea es la misma. Un puntero tambien
es el smbolo que representa la posici on del raton en una pantalla gr aca. Estos punteros tambien
se usan para sealar objetos: enlaces, opciones de men u, botones, etc. Un puntero sirve, pues, para
apuntar a los objetos a los que nos estamos reriendo.
Pues en C++ un puntero es exactamente lo mismo. Probablemente habr as notado que a lo largo
del curso nos hemos referido a variables, constantes, etc como objetos. Esto ha sido intencionado por
el siguiente motivo:
C++ est a dise nado para la programaci on orientada a objetos (POO), y en ese paradigma, todas
las entidades que podemos manejar son objetos. Los punteros en C++ sirven para se nalar objetos,
y tambien para manipularlos. Para entender que es un puntero veremos primero como se almacenan
los datos en un ordenador. La memoria de un ordenador est a compuesta por unidades basicas lla-
madas bits. Cada bit s olo puede tomar dos valores, normalmente denominados alto y bajo, 1 y 0.
Pero trabajar con bits no es practico, y por eso se agrupan. Cada grupo de 8 bits forma un byte u
octeto. En realidad el microprocesador, y por lo tanto nuestro programa, solo puede manejar direc-
tamente bytes o grupos de dos o cuatro bytes. Para acceder a los bits hay que acceder antes a los bytes.
Cada byte de la memoria de un ordenador tiene una direcci on, llamada direccion de memoria.
Los microprocesadores trabajan con una unidad basica de informacion, a la que se denomina pa-
labra (en ingles word). Dependiendo del tipo de microprocesador una palabra puede estar compuesta
por uno, dos, cuatro, ocho o dieciseis bytes. Hablaremos en estos casos de plataformas de 8, 16, 32, 64
o 128 bits. Se habla indistintamente de direcciones de memoria, aunque las palabras sean de distinta
longitud. Cada direccion de memoria contiene siempre un byte. Lo que suceder a cuando las palabras
sean, por ejemplo, de 32 bits es que accederemos a posiciones de memoria que ser an m ultiplos de 4.
Por otra parte, la mayor parte de los objetos que usamos en nuestros programas no caben en una
direcci on de memoria. La soluci on utilizada para manejar objetos que ocupen m as de un byte es
usar posiciones de memoria correlativas. De este modo, la direcci on de un objeto es la direcci on de
memoria de la primera posicion que contiene ese objeto.
Dicho de otro modo, si para almacenar un objeto se precisan cuatro bytes, y la direcci on de memoria
de la primera posicion es n, el objeto ocupar a las posiciones desde n a n + 3, y la direccin del objeto
ser a, tambien, n.
Ahora veamos como funcionan los punteros. Un puntero es un tipo especial de objeto que contie-
36
ne, ni mas ni menos que, la direcci on de memoria de un objeto. Por supuesto, almacenada a partir de
esa direccion de memoria puede haber cualquier clase de objeto: un char, un int, un oat, un array,
una estructura, una funci on u otro puntero. Seremos nosotros los responsables de decidir ese conteni-
do, al declarar el puntero. De hecho, podramos decir que existen tantos tipos diferentes de punteros
como tipos de objetos puedan ser referenciados mediante punteros. Si tenemos esto en cuenta, los
punteros que apunten a tipos de objetos distintos, ser an tipos diferentes. Por ejemplo, no podemos
asignar a un puntero a char el valor de un puntero a int.
En principio, debemos asignar a un puntero, o bien la direccion de un objeto existente, o bien la
de uno creado explcitamente durante la ejecuci on del programa o un valor conocido que indique que
no seala a ning un objeto, es decir el valor 0. El sistema operativo, cuanto m as avanzado es, mejor
suele controlar la memoria. Ese control se traduce en impedir el acceso a determinadas direcciones
reservadas por el sistema.
Declaraci on
Todos los punteros como los objetos se declaran seg un:
<tipo> *<identificador>;
Ejemplos:
int *pEntero;
char *pCaracter;
struct stPunto *pPunto;
Debemos ser cuidadosos al declarar mas de un puntero a la vez. Escribir:
int *x,*y;
No es lo mismo que:
int *x,y
Pues en la ultima, solo x es un puntero.
Como todos los objetos, los punteros tambien contienen basuracuando son declarados. Es costumbre
dar valores iniciales nulos a los punteros que no apuntan a ning un sitio concreto:
int *pEntero = 0; // Tambien podemos asignar el valor NULL
char *pCaracter = 0;
NULL es una constante, que esta denida como cero en varios cheros de cabecera, como cstdio.
o
ostream, y normalmente vale 0L. Sin embargo, hay muchos textos que recomiendan usar el valor 0
para asignar a punteros nulos, al menos en C++.
37
Obtener punteros a objetos
Los punteros apuntan a objetos, por lo tanto, lo primero que tenemos que saber hacer con nuestros
punteros es asignarles direcciones de memoria validas de objetos. Para averiguar la direcci on de
memoria de cualquier objeto usaremos el operador de direccin (&), que leeremos como direcci on
de. Por supuesto, los tipos tienen que ser compatibles; no podemos almacenar la direcci on de un
objeto de tipo char en un puntero de tipo int:
int A;
int *pA;
pA = &A;
Seg un este ejemplo, pA es un puntero a int que apunta a la direccion donde se almacena el valor
del entero A.
Obtener el objeto apuntado por un puntero
La operaci on contraria es obtener el objeto referenciado por un puntero, con el n de manipularlo,
ya sea modicando su valor u obteniendo el valor actual. Para manipular el objeto apuntado por un
puntero usaremos el operador de indireccion, que es un asterisco (*), el cual podemos leerlo como
.
o
bjeto apuntado por:
int *pEntero;
int x = 10;
int y;
pEntero = &y;
*pEntero = x;
En la ultima lnea asignamos al objeto apuntado por pEntero en valor del objeto x. Como pEntero
apunta al objeto y, esta sentencia equivale (segn la secuencia del programa), a asignar a y el valor de
x.
Punteros y Arrays
En muchos aspectos, existe una equivalencia entre arrays y punteros. De hecho, cuando declaramos
un array estamos haciendo varias cosas a la vez:
1. Declaramos un puntero del mismo tipo que los elementos del array.
2. Reservamos memoria para todos los elementos del array. Los elementos de un array se almacenan
internamente en la memoria del ordenador en posiciones consecutivas.
3. Se inicializa el puntero de modo que apunte al primer elemento del array.
Las diferencias entre un array y un puntero son dos:
38
1. Que el identicador de un array se comporta como un puntero constante, es decir, no podemos
hacer que apunte a otra direccin de memoria.
2. Que el compilador asocia, de forma automtica, una zona de memoria para los elementos del
array, cosa que no hace para los elementos apuntados por un puntero corriente.
int vector[10];
int *puntero;
puntero = vector; /* Equivale a puntero = &vector[0]; (1)
esto se lee como "direccin del primer elemento de vector" */
(*puntero)++; /* Equivale a vector[0]++; (2) */
puntero++; /* puntero equivale a asignar a puntero el valor &vector[1] (3) */
La correspondencia entre arrays y punteros tambien afecta al operador []. Es decir, podemos usar los
corchetes con punteros, igual que los usamos con arrays. Pero incluso podemos ir m as lejos, ya que
es posible usar ndices negativos. Por ejemplo, las siguientes expresiones son equivalentes:
*(puntero + 7);
puntero[7];
Punteros a estructuras
Los punteros tambien pueden apuntar a estructuras. En este caso, para referirse a cada elemento
de la estructura se usa el operador ( >), en lugar del (.).
Valor y Referencia
Hasta ahora siempre hemos declarado los par ametros de nuestras funciones del mismo modo. Sin
embargo, este no es el unico modo que existe para pasar parametros.
La forma en que hemos declarado y pasado los par ametros de las funciones hasta ahora es la que
normalmente se conoce como por valor. Esto quiere decir que cuando el control pasa a la funci on,
los valores de los parametros en la llamada se copian a objetos locales de la funcion, estos objetos
son de hecho los propios parametros.
Lo veremos mucho mejor con un ejemplo:
#include <iostream>
using namespace std;
int funcion(int n, int m);
int main() {
int a, b;
39
a = 10;
b = 20;
cout << "a,b ->" << a << ", " << b << endl;
cout << "funcion(a,b) ->"
<< funcion(a, b) << endl;
cout << "a,b ->" << a << ", " << b << endl;
cout << "funcion(10,20) ->"
<< funcion(10, 20) << endl;
return 0;
}
int funcion(int n, int m) {
n = n + 2;
m = m - 5;
return n+m;
}
Empezamos haciendo a = 10 y b = 20, despues llamamos a la funcin funcioncon las objetos a y b
como par ametros. Dentro de funcion.
es
os par ametros se llaman n y m, y sus valores son modicados.
Sin embargo al retornar a main, a y b conservan sus valores originales.
La respuesta es que lo que pasamos no son los objetos a y b, sino que copiamos sus valores a los
objetos n y m.
Referencias a objetos
Las referencias sirven para denir .
a
lias.
o
nombres alternativos para un mismo objeto. Para ello
se usa el operador de referencia (&).
<tipo> &<alias> = <objeto de referencia>
<tipo> &<alias>
La primera forma es la que se usa para declarar objetos que son referencias, la asignaci on es obligatoria
ya que no pueden denirse referencias indeterminadas. La segunda forma es la que se usa para denir
par ametros por referencia en funciones, en estos casos, las asignaciones son implcitas:
#include <iostream>
using namespace std;
int main() {
int a;
int &r = a;
40
a = 10;
cout << r << endl;
return 0;
}
En este ejemplo los identicadores a y r se reeren al mismo objeto, cualquier cambio en una de ellos
se produce en el otro, ya que son, de hecho, el mismo objeto.
Pasar referencia a funciones
Si queremos que los cambios realizados en los parametros dentro de la funci on se conserven al
retornar de la llamada, deberemos pasarlos por referencia. Esto se hace declarando los parametros de
la funcion como referencias a objetos. Por ejemplo:
#include <iostream>
using namespace std;
int funcion(int &n, int &m);
int main() {
int a, b;
a = 10; b = 20;
cout << "a,b ->" << a << ", " << b << endl;
cout << "funcion(a,b) ->" << funcion(a, b) << endl;
cout << "a,b ->" << a << ", " << b << endl;
/* cout << "funcion(10,20) ->"
<< funcion(10, 20) << endl; // (1)
es ilegal pasar constantes como parmetros cuando
estos son referencias */
return 0;
}
int funcion(int &n, int &m) {
n = n + 2;
m = m - 5;
return n+m;
}
En este caso, los objetos a y b tendr an valores distintos despues de llamar a la funci on. Cualquier
cambio de valor que realicemos en los par ametros dentro de la funci on, se har a tambien en los objetos
referenciadas.
41
Punteros como parametros
Cuando pasamos un puntero como parametro de una funci on por valor pasa lo mismo que con
cualquier otro objeto.
Dentro de la funcion trabajamos con una copia del par ametro, que en este caso es un puntero.
Por lo tanto, igual que pasaba con el ejemplo anterior, las modicaciones en el valor del parametro
ser an locales a la funci on y no se mantendrn despues de retornar.
Sin embargo, no sucede lo mismo con el objeto apuntado por el puntero, puesto que en ambos
casos sera el mismo, ya que tanto el puntero como el par ametro tienen como valor la misma direc-
ci on de memoria. Por lo tanto, los cambios que hagamos en los objetos apuntados por el puntero se
conservaran al abandonar la funci on.
Para pasar un puntero por referencia se utiliza:
void funcion(int* &q);
Practica: Realice un ejemplo y estudie como se comporta el puntero y el valor apuntado por este al
aplicar la funcion:
void funcion(int *q) {
*q += 50;
q++;
}
Comparelo con la funci on:
void funcion(int * &q) {
*q += 50;
q++;
}
Argumentos en la funci on main
Hasta ahora siempre hemos usado la funci on main sin parametros, sin embargo, como veremos
ahora, se pueden pasar argumentos a nuestros programas a traves de los par ametros de la funci on
main.
Para tener acceso a los argumentos de la lnea de comandos hay que declararlos en la funci on
main, la manera de hacerlo puede ser una de las siguientes:
int main(int argc, char *argv[]);
int main(int argc, char **argv);
42
Que son equivalentes (recordemos la relaci on entre punteros y arrays). El primer par ametro, argc
(argument counter), es el n umero de argumentos que se han especicado en la lnea de comandos. El
segundo, argv, (argument values) es un array de cadenas que contiene los argumentos especicados
en la lnea de comandos.
Por ejemplo, si nuestro programa se llama programa, y lo ejecutamos con la siguiente lnea de
comandos:
programa arg1 arg2 arg3 arg4
argc valdr a 5, ya que el nombre del programa tambien se cuenta como un argumento.
argv[] contendr a la siguiente lista: C : \programasc\programa, arg1, arg2, arg3 y arg4.
Sobrecarga
Anteriormente hemos visto operadores que tienen varios usos, como por ejemplo , &, << o >>.
Esto es lo que se conoce en C++ como sobrecarga de operadores. Con las funciones existe un meca-
nismo analogo, de hecho, en C++, los operadores no son sino un tipo especial de funciones, aunque
eso s, algo peculiares.
As que en C++ podemos denir varias funciones con el mismo nombre, con la unica condicion
de que el n umero y/o el tipo de los argumentos sean distintos. El compilador decide cual de las
versiones de la funcion usar a despues de analizar el n umero y el tipo de los par ametros. Si ninguna
de las funciones se adapta a los parametros indicados, se aplicar an las reglas implcitas de conversi on
de tipos.
Por ejemplo:
#include <iostream>
using namespace std;
int mayor(int a, int b);
int mayor(int a, int b, int c);
int mayor(int a, int b, int c, int d);
int main() {
cout << mayor(10, 4) << endl;
cout << mayor(15, 35, 23) << endl;
cout << mayor(10, 12, 12, 18) << endl;
return 0;
}
43
int mayor(int a, int b) {
if(a > b) return a; else return b;
}
int mayor(int a, int b, int c) {
return mayor(mayor(a, b), c);
}
int mayor(int a, int b, int c, int d) {
return mayor(mayor(a, b), mayor(c, d));
}
Energa de Rotacion cuantica: Los niveles de energa de rotaci on de un s olido en mecanica cu antica
est an cuantizados y est an dados por la f ormula:
E
rot
=
hl(l + 1)
2I
Donde h es la constante de planck normalizada, l 0 es un n umero entero que determina el nivel de
ener gia e I es el momento de inercia alrededor del eje sobre el cu al rota, dependiente de la forma del
s olido. En un experimento se requiere calcular las energas de una varilla de largo L y masa M que
rota sobre un eje perpendiular que pasa por su centro de masa y un paralelepipedo de lados a, b y
c y masa M que rota sobre un eje perpendicular a una de sus caras, cuyos momentos de inercia son
respectivamente:
I =
1
3
ML
2
I =
M
12
(b
2
+ c
2
)
Escribir una funcion oat ERot(oat I) que arroje los 5 primeros niveles de energas de rotaci on por
pantalla de un s olido de momento de inercia I y oat Inercia(...) con 2 implementaciones diferentes
que calculen el momento de una varilla al pasar 2 argumentos y el de un paraleleppedo al pasar 3.
Recursividad
Se dice que una funci on es recursiva cuando se dene en funcion de si misma.C++ permite la
recursividad. Cada vez que se llama a una funcion, se crea un juego de variables locales, de este
modo, si la funci on hace una llamada a si misma, se guardan sus variables y par ametros, usando la
pila, y la nueva instancia de la funci on trabajara con su propia copia de las variables locales. Cuando
esta segunda instancia de la funcion retorna, recupera las variables y los par ametros de la pila y
continua la ejecuci on en el punto en que hab aa sido llamada.Prodramos crear una funcion recursiva
para calcular el factorial de un n umero entero:
44
int factorial(int n) {
if(n < 0) return 0;
else if(n > 1) return n*factorial(n-1); /* Recursividad */
return 1; /* Condicion de terminacion, n == 1 */
}
Fibonacci: En matem aticas, la sucesi on de Fibonacci (a veces mal llamada serie de Fibonacci) es la
siguiente sucesi on innita de n umeros naturales:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377 . . .
La sucesion comienza con los n umeros 0 y 1, y a partir de estos, cada elemento es la suma de los dos
anteriores. Escriba una funci on bonacci(int n) que retorne los n primeros n umeros de bonacci.
N umeros de Catalan: En combinatoria, los n umeros de Catalan forman una secuencia de n umeros
naturales que aparece en varios problemas de conteo que habitualmente son recursivos. Se denen
como:
Y asintoticamente, estos crecen como:
Escribir un programa catalan(int n) que arroje los primeros n n umeros de catalan. Adem as, escriba
una funcion errorCat(oat catalan) que entregue la diferencia entre el n umero de catal an y el n umero
asint otico. Haga que imprima este error por pantalla luego de mostrar el n umero.
Clases
A continuacion veremos una de las herramientas mas fuertes de C++: las Clases. Antes de aden-
trarnos en este mundo veremos algunos concepetos de POO (programaci on orientada a objetos) que
es el modo en el cual esta diseado C++.
Conceptos fundamentales
Objeto
Un objeto es una unidad que engloba en s mismo datos y procedimientos necesarios para el tra-
tamiento de esos datos.
45
Hasta ahora habamos hecho programas en los que los datos y las funciones estaban perfectamente
separadas, cuando se programa con objetos esto no es as, cada objeto contiene datos y funciones. Y
un programa se construye como un conjunto de objetos, o incluso como un unico objeto.
Mensaje
El mensaje es el modo en que se comunican e interrelacionan los objetos entre si.
En C++, un mensaje no es mas que una llamada a una funcion de un determinado objeto. Cuando
llamemos a una funcion de un objeto, muy a menudo diremos que estamos enviando un mensaje a
ese objeto.
Metodo
Se trata de otro concepto de POO, los mensajes que lleguen a un objeto se procesar an ejecutando
un determinado metodo de ese objeto.
En C++ un metodo no es otra cosa que una funci on o procedimiento perteneciente a un objeto.
Clase
Una clase se puede considerar como un patr on para construir objetos.
En C++, un objeto es s olo una instancia (un ejemplar) de una clase determinada. Es importan-
te distinguir entre objetos y clases, la clase es simplemente una declaracion, no tiene asociado ning un
objeto, de modo que no puede recibir mensajes ni procesarlos, esto unicamente lo hacen los objetos.
Interfaz
Se trata de la parte del objeto que es visible para el resto de los objetos. Es decir, que es el
conjunto de metodos (y a veces datos) de que dispone un objeto para comunicarse con el.
Las clases y por lo tanto tambien los objetos denidos a partir de ellas, tienen partes p ublicas y
partes privadas. Generalmente, llamaremos a la parte p ublica de una clase u objeto su interfaz.
Herencia
Es la capacidad de crear nuevas clases basandose en clases previamente denidas, de las que se
aprovechan ciertos datos y metodos, se desechan otros y se aaden nuevos.
Veremos que es posible dise nar nuevas clases bas andose en clases ya existentes. En C++ esto se
llama derivaci on de clases, y en POO herencia. Cuando se deriva una clase de otras, normalmente se
aadir an nuevos mtodos y datos. Es posible que algunos de estos metodos o datos de la clase original
no sean v alidos, en ese caso pueden ser enmascarados en la nueva clase o simplemente eliminados. El
conjunto de datos y metodos que sobreviven, es lo que se conoce como herencia.
46
Jerarqua
Denici on del orden de subordinaci on de un sistema clases.
En POO la herencia siempre se produce en un mismo sentido: se toman una o varias clases base
y se crean clases nuevas que heredan parte de las caractersticas de las clases de las que procede.
Este procedimiento crea estructuras de clases en forma de arbol, en las que siempre es posible retro-
ceder hasta una o varias clases base.
Veremos que la jerarqua es importante cuando hablemos de conceptos como polimorsmo.
Polimorsmo
La denici on del diccionario es: Cualidad de lo que tiene o puede tener distintas formas. Esto ya
nos da alguna pista. En POO este concepto es similar:
Propiedad seg un la cual un mismo objeto puede considerarse como perteneciente a distintas cla-
ses. Esta propiedad se presenta solo en objetos declarados a partir de una clase derivada. Nos permite
tratar el mismo objeto como si hubiese sido declarado a partir de alguna de las clases base.
La idea b asica es bastante simple. Por ejemplo, en una jerarqua como: partcula, fermion, lepton,
muon; un objeto creado de la clase mu on podra tratarse, seg un nos convenga, como un fermion, un
lept on, o como un objeto de cualquier clase de la jerarqua.
Si en la misma jerarqua derivamos de la clase lept on otras clases como tau, electr on y neutrino
mu onico, en determinadas circunstancias podramos considerar de la misma clase objetos de las cla-
ses tau, muon, electr on y neutrino mu onico. Podramos, por ejemplo, almacenarlos todos en un array
de leptones.
Denici on de Clases
class <identificador de clase> [<:lista de clases base>] {
<lista de miembros>
} [<lista de identificadores de objetos>];
La lista de clases base se usa para derivar clases, de momento no le prestes demasiada atenci on, ya
que por ahora solo declararemos clases base.
La lista de miembros ser a en general una lista de funciones y datos.
Los datos se declaran del mismo modo en que lo hacamos hasta ahora, salvo que no pueden ser
inicializados, recuerda que estamos hablando de declaraciones de clases y no de deniciones de objetos.
Las funciones pueden ser simplemente declaraciones de prototipos, que se deben denir aparte de la
clase pueden ser tambien deniciones.
Cuando se denen fuera de la clase se debe usar el operador de ambito (::). Veamos un ejemplo:
class Photon{
public:
double Energy;
47
void ObtainFrecuency(double &f){
f=Energy/0.00000000000000413566;
}
};
::void Photon::SetEnergy(E){
Energy=E;
}
Especicadores de Acceso
Dentro de la lista de miembros, cada miembro puede tener diferentes niveles de acceso.
class <identificador de clase> {
public:
<lista de miembros>
private:
<lista de miembros>
protected:
<lista de miembros>
};
Acceso privado, private
Los miembros privados de una clase s olo son accesibles por los propios miembros de la clase y en
general por objetos de la misma clase, pero no desde funciones externas o desde funciones de clases
derivadas.
Acceso p ublico, public
Cualquier miembro p ublico de una clase es accesible desde cualquier parte donde sea accesible el
propio objeto.
Acceso protegido, protected
Con respecto a las funciones externas, es equivalente al acceso privado, pero con respecto a las
clases derivadas se comporta como p ublico.
Cada una de estas palabras, seguidas de :, da comienzo a una seccion, que terminara cuando
se inicie la seccion siguiente o cuando termine la declaraci on de la clase. Es posible tener varias sec-
ciones de cada tipo dentro de una clase.
Si no se especica nada, por defecto, los miembros de una clase son privados.
48
Constructores
Los constructores son funciones miembro especiales que sirven para inicializar un objeto de una
determinada clase al mismo tiempo que se declara.
Los constructores son especiales por varios motivos:
1. Tienen el mismo nombre que la clase a la que pertenecen.
2. No tienen tipo de retorno, y por lo tanto no retornan ning un valor.
3. No pueden ser heredados.
4. Por ultimo, deben ser p ublicos, no tendra ning un sentido declarar un constructor como privado,
ya que siempre se usan desde el exterior de la clase, ni tampoco como protegido, ya que no puede
ser heredado.
class <identificador de clase> {
public:
<identificador de clase>(<lista de parmetros>) [: <lista de constructores>] {
<cdigo del constructor>
}
...
}
Por ejemplo para nuestra clase Photon.
class Photon{
public:
double Energy;
\\Constructor
Photon(float E){
Energy=E;
}
\\Funciones
void ObtainFrecuency(double &f){
f=Energy/0.00000000000000413566;
}
};
::void Photon::SetEnergy(E){
Energy=E;
}
Para crear un objeto de la clase determinada con el constructor, debemos ocupar la sintaxis:
<identificador de la clase> <nombre del objeto>(lista de parametros)
Por ejemplo:
Photon P1(1023.34)
49
Constructor por defecto
Cuando no especiquemos un constructor para una clase, el compilador crea uno por defecto sin
argumentos. Cuando se crean objetos locales, los datos miembros no se inicializaran, contendran
la basuraque hubiese en la memoria asignada al objeto. Si se trata de objetos globales, los datos
miembros se inicializan a cero.
La expresion:
Photon P1();
Se trata de un error frecuente cuando se empiezan a usar clases, lo correcto es declarar el objeto sin
usar los parentesis:
Photon P1;
Inicializador
Hay un modo especco para inicializar los datos miembros de los objetos en los constructores,
que consiste en invocar los constructores de los objetos miembro antes de las llaves de la denicion
del constructor.
S olo los constructores de las clases admiten inicializadores. Cada inicializador consiste en el nom-
bre de la variable miembro a inicializar, seguida de la expresi on que se usar a para inicializarla entre
parentesis. Los inicializadores se aadiran a continuacion del parentesis cerrado que encierra a los
par ametros del constructor, antes del cuerpo del constructor y separado del parentesis por dos puntos
:.
Por ejemplo en vez de escribir:
Photon(float E){
Energy=E;
}
Podemos escribir:
Photon(float E) : Energy(E) {}
Ciertos miembros es obligatorio inicializarlos, ya que no pueden ser asignados, por ejemplo las
constantes o las referencias. Es preferible usar la inicializacion siempre que sea posible en lugar de
asignaciones, ya que frecuentemente, es menos costoso y mas predecible inicializar objetos en el
momento de la creaci on que usar asignaciones.
Sobrecarga de constructores
Como los constructores son funciones, podemos tambien denir varios constructores en una clase.
Por ejemplo, podemos simular el constructor por defecto en la clase Photon:
50
\class Photon{
public:
double Energy;
\\Constructor
Photon(float E) : Energy(E){}
Photon() : Energy(0){}
\\Funciones
void ObtainFrecuency(double &f){
f=Energy/0.00000000000000413566;
}
};
::void Photon::SetEnergy(E){
Energy=E;
}
Otra forma de simular el constructor por defecto sera con valores por defecto:
\class Photon{
public:
double Energy;
\\Constructor
Photon(float E=0) : Energy(E){}
\\Funciones
void ObtainFrecuency(double &f){
f=Energy/0.00000000000000413566;
}
};
::void Photon::SetEnergy(E){
Energy=E;
}
Copia de objetos
Podemos copiar un objeto de determinada clase con otro de la misma mediante el operador de
asignaci on:
Manejo de archivos de texto
Estructuras de datos: Listas
Analisis estadstico de datos en Root
Es tiempo de adentrarnos en Root. Para ello, en el siguiente captulo revisaremos conceptos fun-
damentales del analisis de datos estadsticos en fsica (especialmente en fsica de partculas) y para-
lelamente veremos como se ocupa Root para estos an alisis.
Arquitectura de Root
De los conceptos de la programaci on orientada a objetos vimos que Clase es una especie de des-
cripci on de alg un ente con el que trabajaremos en el programa, Objeto es la instancia de esa clase
y Metodo son las funciones que pueden operar en esa clase. Root est a compuesto por alrededor de
1200 clases, distribuidas en 60 libreras y agrupadas en 19 categoras. Cada una de estas clases (Como
TString, TH1F, TNtuple, etc.) son heredadas de la clase madre TObject. Es recomendable revisar la
p agina del software http://root.cern.ch para tener una visualizacion y profundizacion mas completa
de estas clases (vease Class Index y Class Hierarchy).
Para Root, ahora que podemos programar en C++ y conocemos conceptos relativos a la manera en
la que se distribuye y se lleva a cabo la programacion, nos centramos en la creacion de Histogramas
y Gracos; el an alisis de estos por medio de Fits o ajustamientos de curva, obteniendo todos los
par ametros necesarios de conabilidad y error; y el manejo y almacenamiento de datos en arboles
por medio de clases como TTree y TNtuple, con su respectivo uso en simulaciones (Veremos esto mas
profundamente cuando nos adentremos en Geant4).
Luego de instalado Root, para entrar en el software debemos teclear:
root
Y se iniciar a root. Si no queremos que aparezca el logo, tecleamos:
root -l
Lnea de comandos de Root
Para abrir un programa hecho en C++ con Root, debemos teclear en la terminal con Root abierto:
.x [filename]
Esto cargar a y ejectura el programa. Si queremos usar comandos de la terminal en una sesi on con
Root abierto debemos anteponer un .! al comando.
51
52
Tipos independientes
Root posee tipos de variables independientes. La unica diferencia con los tipos de variables de
C++, es que deben empezar con may uscula y terminar con t. Por ejemplo, int es Int t en Root.
Conceptos fundamentales de Estadstica
Errores experimentales
Existen dos tipos de experimentos que un cientco puede llevar a cabo: el primero es determi-
nar el valor numerico de una cantidad fsica y el segundo es probar si una determinada teora es
consistente con nuestros datos. El primero est a relacionado con la Determinacion de parametros y
el segundo con los test de hipotesis. Los errores en las mediciones de las cantidades siempre contie-
nen errores que hacen la determinacion de par ametros y el chequeo de hipotesis bastante complicados.
Para la determinacion de un parametro, consideramos siempre no s olo el valor de la magnitud fsica
medida, si no tambien su presicion.

Esta presici on se expresa mediante el error experimental de la
cantidad de interes. Por ejemplo:
c = (3,09 0,15) 10
8
[m/s]
Estos errores experimentales pueden ser sistematicos o aleatorios. Para entenderlos consideremos
un experimento centrado en determinar la constante de decaimiento de un elemento radioactivo.
Las medidas necesarias consisten en contar cuantos decaimientos son observados en un determinado
tiempo (dn/dt). Luego, la constante puede ser calculada como:

dn
dt
= n
El error aleatorio viene del hecho de que hay un error estadstico inherente en el conteo de los
eventos. Es decir, el error aleatorio se produce por la inhabilidad nstural de tener presici on innita.
Los errores sistem aticos pueden deberse a que los contadores no son totalmente ecientes, no son lo
sucientemente sensibles o bien que el material radioactivo no es puro. Es decir, los errores sistematicos
se producen por errores en ls conguraci on del proceso de medici on.
Estadstica descriptiva
Debido los errores, es necesario tomar mediciones de una magnitud variadas veces, observar los
distintos valores que estos toma y en base al an alisis de estos datos determinar el mejor valor de la
cantidad. Para ello, tenemos herramientas utiles de estadstica descriptiva que nos pueden ayudar.
Este an alisis tambien sirve para estudiar determinadas caractersticas cualitativas o cuantitativas de
un sistema en su conjunto (por ejemplo temperatura de una zona, densidades promedio de suelos,
etc.)
53
Histogramas
Un histograma es una representacion graca de una variable en forma de barras, donde la super-
cie de cada barra es proporcional a la frecuencia de los valores representados. Sirven para obtener
un panorama de la distribuci on de la poblacion, o la muestra, respecto a una caracterstica, cuanti-
tativa y continua, de la misma. As pues, podemos evidenciar comportamientos, observar el grado de
homogeneidad, acuerdo o concision entre los valores de todas las partes que componen la poblacion
o la muestra, o, en contraposicion, poder observar el grado de variabilidad, y por ende, la dispersion
de todos los valores que toman las partes.
Ac a por ejemplo, podemos ver un histograma de una distribuci on de momentum generada por Root
Para poder comprender como se generan y se dibujan los histogramas en Root, primero estudia-
remos algunas clases fundamentales:
Clase TCanvas
Esta clase es una especie de area (Canvas quiere decir Lienzo) sobre la cual dibujaremos todo.
El TCanvas permanece abierto como una plataforma de manejo gr aco y f acil al usuario. Adem as,
podemos tener variados TCanvas abiertos con distintos dibujos en el. Para generar un TCanvas
recurrimos al constructor principal (para otros constructores de TCanvas y cualquier clase, vease el
Class Index de Root):
TCanvas * c1 = new TCanvas("nombre", "titulo", ancho, alto);
Si lo escribimos en la terminal con Root activo, veremos como nos arroja inmediantamente el lienzo
sobre el cual trabajaremos. El TCanvas tambien se divide en sub- areas de trabajo llamados Pads.
Un metodo de TCanvas que permite dividirlo en Pads es Divide. Por ejemplo:
c1->Divide(2,3)
54
Dividir a el TCanvas en 6 mini-lienzos distribuidos en forma 2 3. Para situarnos en un determinado
Pad, debemos aplicar el metodo cd el cual funciona as:
c1->cd(numero de Pad)
Ac a, nos situaremos en el Pad del n umero se nalado.
Clase TF1, TF2, TF3
Estas clases son funciones. Denen funciones en 1D, 2D y 3D respectivamente. Las funciones se
generan de las formas:
TF1*f1=new TF1("nombre","formula", xmin, xmax);
TF2*f2=new TF2("nombre","formula", xmin, xmax, ymin, ymax);
TF3*f3=new TF3("nombre","formula", xmin, xmax, ymin, ymax, zmin, zmax)
Y para dibujarlas en el TCanvas debemos usar el metodo Draw:
f1->Draw()

Este metodo no solo sirve para dibujar funciones, si no que cualquier cosa que se pueda dibujar en
Root. Esto incluye tambien a los histogramas.
El metodo Draw() tiene variadas opciones que permiten modicar como se dibujara el objeto (revisar
documentaci on). Otros metodos de TF(1-2-3) son Eval, Derivative, Integral, entre otros.
Clase Histogramas
Estas clases tienen los nombres TH(1-2-3)(S-D-F-I-C). Dependiendo de las dimensiones y de el
tipo de variable de los datos. Por ejemplo TH2F es un histograma de dos dimensiones en variables
tipo oat. Un mapa con la herencia de la clase histograma se encuentra a continuaci on:
Para crear Histogramas podemos recurrir al constructor:
TH1*h1=new TH1F("nombre","titulo",numero de bins en x, xmin, xmax);
Los bins son los subintervalos en los cuales se divide el eje de valores que puede tomar la magnitud.
Para mayores dimensiones, se escriben a continuacion los numeros de bins de y y z y sus respectivos
m aximos y mnimos.:
TH3*h3=new TH3F("nombre","titulo",numero de bins en x, xmin, xmax,
numero de bins en y, ymin, ymax, numero de bins en z, zmin, zmax);
Los histogramas contienen tres objetos TAxis: los ejes x, y, z. Por medio de metodos podemos
llamarlos y guardarlos en variables:
TAxis*xAxis=h1->GetXaxis();
As mismo podemos obtener lmites y centros de los bins por medio de metodos a los TAxis:
55
xAxis->GetBinLowEdge(numero del bin);
xAxis->GetBinCenter(numero del bin);
xAxis->GetBinUpEdge(numero del bin);
Tambien podemos guardar un bin como variable:
Int_t bin=h3->GetBin(binx,biny,binz)
Para llenar histogramas usamos el metodo Fill de la forma:
h->Fill(binx);
h->Fill(binx,weight);
h->Fill(binx, biny);
h->Fill(binx, biny, binz, weight)
El metodo llena el respectivo bin con el peso denotado. Si no se denota, se incrementa en uno
el contenido del bin. Podemos incrementar el contenido del bin directamente con AddBinContent,
cambiarlo con SetBinContent y acceder al contenido por medio de GetBinContent:
Double_t contentbin=h->GetBinContent(numero del bin);
Otros metodos de llenado son por medio de generadores aleatorios. El metodo FillRandom sirve
para llenar un histograma aleatoriamente con la distribuci on de alguna funci on o alg un otro histo-
grama. Por ejemplo:
h1->FillRandom("gaus",10000)
Llena el histograma con 10000 entradas de una distribuci on Normal(0,1). Podemos tambien llenarlo
aleatoriamente con alguna funcion que denamos:
TF1*f=new TF1("funcion","Sin(x)",0,100);
h1->FillRandom("funcion",10000)
O bien con algun histograma anterior:
h2->FillRandom(&h1,10000)
El estilo del histograma lo podemos modicar con variadas opciones y metodos que se encuentran
tambien en la documentaci on.
Recomendamos ver los ejemplos que se encuentran en los tutoriales de Root, entenderlos y preguntar
en clases.
56
Promedio y varianza de una muestra
Para cualquier muestra de tama no N con datos x
i
cada uno con frecuencia n
i
, podemos obtener
el promedio ( x) y la varianza (s
2
) de ella de acuerdo a las formulas:
x =
1
N

x
i
n
i
s
2
=
1
N 1

n
i
(x
i
x)
2
Estas magnitudes son muestrales, es decir, presentan solo una aproximaci on de los verdaderos pro-
medios y varianzas de la poblacion total y son obtenidos mediante estimacion de par ametros. Si
conocemos el promedio real , entonces la varianza real ser a:

2
=
1
N

n
i
(x
i
)
2
Y la desviaci on:
=

1
N

n
i
(x
i
)
2
Asimetra
El promedio nos indica una especie de valor representativo de todos los valores obtenidos en la
muestra y la varianza nos indica la dispersi on de los datos.
Como estas, la medida de asimetra nos permite identicar si los datos se distribuyen de forma
uniforme alrededor del punto central (promedio). La asimetra presenta tres estados diferentes , cada
uno de los cuales dene de forma concisa como estan distribuidos los datos respecto al eje de asimetra:
El coeciente de asimetra de Fisher entrega una medida cuantitativa de esta propiedad. Antes
de conocerlo, primero revisaremos el concepto de momento central de orden n de una distribuci on
estadstica discreta. Se calcula como:

n
=
1
N

n
i
(x
i
x)
n
Luego el coeciente de Fisher es:

1
=

3

3
57
Si
1
= 0, se acepta una distribucion simetrica; si
1
> 0, hay asimetra positiva y si
1
< 0, existe
asimetra negativa.
Practica: Escriba un programa en C++ que permita calcular el coeciente de asimetra de Fisher
de un conjunto de datos entregados como arreglo (de un maximo de 10000) y que nos entregue
textualmente la forma de la distribuci on respecto a su asimetra. Con ayuda de esta funci on, escriba
un programa en Root que genere un histograma con 5000 entradas una distribucion que usted escoja.
Extraiga los datos y verique gr acamente que la asimetra es coincidente con lo que entrega el
programa. Hint: Escriba funciones para el promedio y la varianza.
Curtosis
Esta medida determina el grado de concentraci on que presentan los valores en la region central de
la distribuci on. Por medio del Coeciente de Curtosis, podemos identicar si existe una gran concen-
tracin de valores (Leptoc urtica), una concentraci on normal (Mesoc urtica) o una baja concentracion
(Platic urtica).
El coeciente de Curtosis de calcula como:

2
=

4

4
3
Si
2
es cercana a 0, la distribuci on es mesoc urtica, si
2
> 0, es Leptoc urtica y si
2
< 0 es planic urtica.
Practica: Haga lo mismo que en la seccion anterior, pero esta vez con el coeciente de curtosis.
Variables aleatorias y probabilidad
Una caracterstica es aleatoria si no se sabe o no puede ser predecida con completa certeza. El
grado de aleatoriedad de una variable es cuanticada por el concepto de probabilidad. Consideremos
un espacio S de un cierto n umero de elementos o sucesos. Para cada subconjunto A de S podemos
asignar un n umero P(A) llamado probabilidad que satisface:
1. Para cada A en S; P(A) 0.
2. Para dos conjuntos A y B disjuntos, la probabilidad de la union entre A y B es la suma de las
probabilidades: P(A B) = P(A) + P(B).
3. La probabilidad del espacio entero es 1: P(S) = 1.
58
Practica: Demuestre con estos axiomas:
P(A
c
) = 1 P(A); (A
c
es el complemento de A)
P(A A
c
) = 1
0 P(A) 1
P() = 0
P(A B) = P(A) + P(B) P(A B)
Probabilidad condicional
Consideremos un prot on y un electr on. Supongamos que introducimos el prot on en una caja
aislada.Seg un la mecanica cuantica el prot on tiene cierta probabilidad de estar en un lugar A de
la caja. Llamemos a esta probabilidad P
(
A
+
). Si ahora introducimos otro electron, sabemos que la
probabilidad de que este electr on este en un espacio B se ve condicionada dependiendo de donde
este el proton en este momento. Luego, si consideramos que P
(
B

) es esta probabilidad, entonces la


probabilidad de que el electron esten en B dado que el proton esta en A se denomina probabilidad
condicional. Se denota P(B

/A
+
) y se calcula:
P(B

|A
+
) =
P(B

A
+
)
P(A
+
)
En general la probabilidad de que ocurra un suceso X dado que ocurri o uno Y se calcula como:
P(X|Y ) =
P(X Y )
P(Y )
Ahora, los sucesos A y B son independientes si:
P(A|B) = P(A) P(A B) = P(A)P(B)
Adem as, podemos deducir una relaci on entre probabilidades condicionales llamado teorema de Bayes:
P(A|B) =
P(B|A)P(A)
P(B)
La probabilidad se puede interpretar como una frecuencia relativa de sucesos determinados. Sin
embargo, otros enfoques los interpretan como el grado de verdad de que el suceso sea verdadero.
Funcion densidad de probabilidad
Consideremos un experimento caracterizado por una variable continua x que puede asumir deter-
minados valores. La probabilidad de que la cantidad se situe en un intervalo [x, x+dx] esta dada por
la funcion de densidad de probabilidad f(x):
probabilidad de observar x en el intervalo [x, x + dx] = f(x)dx
59
En el caso de una variable discreta, la funcion de densidad se denomina funcion de cuanta y entrega
la probabilidad de que la variable aleatoria tome el valor x:
Probabilidad de que X sea igual a x = P(x)
La f.d.p se normaliza requiriendo que la probabilidad total por todo el espacio de sucesos sea 1:

S
f(x)dx = 1
Podemos asemejar la f.d.p con el histograma de datos. En el caso de un histograma, los diferenciales
dx se vuelven discretos como pequeos subintervalos o bins de ancho x
i
el area total bajo la curva
corresponde a la sumatoria de todas las frecuencias multiplicada por el ancho del intervalo respectivo:
A =

n
i
x
i
La f.d.p corresponde a la misma forma del histograma, pero tomando valores de tal forma que el
area total sea 1. La funcion de probabilidad acumulada, se reere a la probabilidad de que la variable
aleatoria pueda tomar cualquier valor hasta un x. En general se calcula, continua y discretamente
como:
F(x) =

x
i
x
P(x
i
)
F(x) =

f(x

)dx

Del teorema fundamental del c alculo se tiene que:


f(x) =
F
x
Si queremos analizar el comportamiento de dos variables aleatorias, podemos denir la f.d.p como:
Probabilidad de que x este en [x, x + dx] e y este en [y, y + dy] = f(x, y)dxdy
Y se normaliza como:

S
f(x, y)dxdy
Para obtener las probabilidades de que x este en [x, x +dx] independiente de y, podemos calcular las
distribuciones marginales:
f
x
(x) =

f(x, y)dy
Lo mismo para y:
f
y
(y) =

f(x, y)dx
Estas corresponden a las proyecciones del histograma normalizado sobre los ejes x e y.
Practica:Encuentre expresiones para calcular probabilidades condicionadas, es decir, dado que y
toma cierto valor, la probabilidad de que x tome otro.
60
Valores esperados
Propagaci on de error
Ejemplos de distribuciones de probabilidad y aplicaciones a
la fsica
Distribuci on binomial
Distribuci on de Poisson
Distribuci on uniforme
Distribuci on exponencial
Distribuci on Normal
Distribuci on Chi-cuadrado
Distribuci on Cauchy
Distribuci on Landau
Metodo de Montecarlo
Estimaci on de parametros y test de hip otesis
Metodo de maxima verosimilitud
Metodo de mnimos cuadrados
Metodo de momentos
Intervalos y lmites de conanza
Analisis de radiacion de partculas a
traves de la materia
61
62
Geant4
63

Вам также может понравиться