Professional Documents
Culture Documents
Rubén Agapito
Verano 2018
Contenidos
Prefacio v
1 Introducción a Octave 1
1.1 Algunas Definiciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Fundamentos de Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1 Problemas Propuestos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3 Bucles For y While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.3.1 Problemas Propuestos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4 Ploteo en Dos Dimensiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.4.1 Problemas Propuestos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5 Simulación Monte Carlo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
ii CONTENIDOS
Programas
Los contenidos de estas notas están bajo constante supervisión. Si existe alguna sugerencia o
error, por favor mandar un correo electrónico al autor: ruben.agapito@pucp.pe
Rubén Agapito
San Miguel, enero de 2018
Lima, Perú.
vi Prefacio
Capítulo 1
Introducción a Octave
Algoritmo de Bisección
INPUT extremos a, b; tolerancia TOL; maximo numero de iteraciones N0 .
OUTPUT solucion aproximada r o mensaje de no exito.
Paso 1: Inicializar i = 1;
Poner F A = f (a).
Paso 2: Mientras que i ≤ N0 hacer Pasos 3-6.
Paso 3: Poner r = a + (b − a)/2; (Calcula los p i )
FR = f (r).
Paso 4: Si FR = 0 o (b − a)/2 < TOL entonces
1
Léase http://es.wikipedia.org/wiki/Algoritmo para más información.
2
Léase http://es.wikipedia.org/wiki/Algoritmo#Pseudoc.C3.B3digo.
3
El requerimiento f (a) · f ( b) < 0 implica que f evaluada en los extremos del intervalo [a, b] toma valores con
signos opuestos y como f es continua la gráfica de la función debe pasar necesariamente por el eje X .
2 Capítulo 1. Introducción a Octave
lugar”, esto es, librerías gráficas, de funciones, de manejo de data, etc. La documentación de
Octave puede ser leída al abrir el GUI (la interface gráfica del software), pero se recomienda,
al estar mejor estructurada y con ejemplos, el manual online del software Matlab:
http://la.mathworks.com/help/matlab/index.html?s_tid=gn_loc_drop
pero en estas notas introduciremos el manejo de este software poco a poco resolviendo proble-
mas.
A ( r ) = 4π r 2 .
∆ A = 4π( r + δ r )2 − 4π r 2 (1.1a)
∆ A = 4π(2 r + δ r ) · δ r (1.1b)
∆ A ≈ 8π r · δ r (1.1c)
Las dos primeras fórmulas son exactas, mientras que la tercera es una aproximación que
ignora el término (δ r )2 .
Escribir un programa en que solicite (input) el radio de la esfera r (en kilómetros), el
incremento δ r (en milímetros), y exhiba (output) en pantalla el incremento en el área de la
superficie (en metros cuadrados). ¿Cuál es el incremento (∆ A ) cuando el radio de un planeta
esférico ( r = 6367 km) se incrementa por unos pocos milímetros (δ r )? Explore la respuesta
a esta pregunta usando cada una de las tres fórmulas dadas arriba.
>> r = 6367;
Ponemos el punto y coma al final de la sentencia y luego presionamos Enter para llevar a cabo
esta asignación en la memoria del computador (¿qué sucede si no hubiésemos puesto el punto
y coma? 5 ). Podemos ahora hallar el área de la esfera usando la variable r :
>> 4 * 3.1416 * r ^2
5
Rpta: Después de presionar Enter, aparte de almacenar la asignación en memoria también se mostrará nue-
vamente esta línea en el prompt de Octave. Además, obsérvese que no hemos tipeado una ecuación, sino una
asignación, el signo de igualdad en Octave está dado por ==, y veremos más adelante cómo utilizarlo.
4 Capítulo 1. Introducción a Octave
ans =
5.0943 e +08
Si deseamos mostrar más dígitos podemos usar el comando format con el estilo long:6
Observemos que Octave utiliza internamente 16 dígitos para sus cálculos (en la mantisa de la
representación punto flotante de un número7 ), pero como en la respuesta final es común usar
de 3 a 5 dígitos, volvemos al formato original usando format short.
Si deseamos usar el área calculada en operaciones posteriores, es preferible almacenar la
respuesta en una variable8 , por ejemplo:
(o function M-files). La diferencia entre ellos es que un programa del tipo función necesita al
ser invocado de uno o más inputs y da como resultado uno o más outputs9 . Un script no necesita
de input al ser invocado. En nuestro caso utilizaremos un script y lo llamaremos AreaSup.m (la
terminación .m es añadida por defecto por el software). Comenzamos invocando el editor de
Octave para tipear el programa:
Para usar este programa hacemos clic izquierdo en el triángulo verde de la parte superior,
etiquetado con Run, o simplemente tipeamos el nombre del script en el Command Window
>> AreaSup
Ingrese radio r :
En caso quiera usarse otro valor para r, simplemente hay que invocar el programa de nuevo.
Pasamos a describir lo que hace cada línea.
Líneas 1-2: Cualquier código escrito a la izquierda del símbolo % es un comentario, y no son
vistos por el compilador a la hora de correr el programa. Los comentarios son útiles para
hacer el código más entendible.
Línea 3: El comando clc borra los contenidos del Command Window, es un acrónimo para
clear command window.
Línea 4: El comando input pide entrada de data al usuario. La sentencia entre signos de após-
trofe es una data del tipo string,11 la cual aparecerá en pantalla al correr el programa.
El radio ingresado se almacenerá en la variable r.
9
Brindaremos varios ejemplos más adelante para que la diferencia entre scripts y funciones quede más claro.
Es posible construir una función que no necesite input y no dé outputs, este tipo de función tiene sus fines, pero
no la usaremos aquí.
10
Dependiendo de la configuración de Octave que uno tenga, es posible que la ventana del Editor aparezca
incrustada en la ventana principal.
11
En caso necesitemos saber más sobre un comando determinado, por ejemplo input, podemos usar los coman-
dos help o doc. Por ejemplo, úsese help input.
6 Capítulo 1. Introducción a Octave
Línea 6: Se exhibe en pantalla la sentencia indicada dentro de los apóstrofes, con los reem-
plazos de %10.3f por el valor almacenado en r y %10.3e por el valor almacenado en A. El
símbolo \n significa Enter o cambio de línea.
Expliquemos ahora el formato %10.3f. Primero recordemos que esta expresión será reempla-
zada por el valor que tenga la variable r, el cual está representando un número real. El número
10 significa que se reservarán 10 espacios en pantalla para el valor de r, incluyendo el punto
decimal. El número 3 significa que se reservarán 3 espacios comenzando desde la derecha para
la parte decimal del valor de r. En caso el valor de r contenga más de 3 cifras decimales, Octave
utilizará redondeo para forzar la exhibición a sólo tres cifras. Quedan entonces 6 espacios libres
para exhibir la parte entera de r. En caso la parte entera contenga más de 6 cifras, entonces
se exhibirá TODA la parte entera de r. Si la parte entera tiene menos de 6 cifras, entonces se
usarán espacios en blanco (a la izquierda del número) para completar los espacios que faltan.
Por último, la letra f indica que se usará notación decimal estándar.12 Otras opciones son %d
(para valores enteros) y %e (para exhibir valores en formato exponencial).
Se recomienda correr el programa para diversos valores de r para entender cómo funciona
este formato.
Ahora nos concentramos en cómo implementar en Octave el incremento del área usando
las tres fórmulas dadas en (1.1a)–(1.1c).
delta_A1 = 4* pi *( r + delta_r ) ^2 - 4* pi * r ^2
delta_A2 = 4* pi *(2* r + delta_r ) * delta_r
delta_A3 = 8* pi * r * delta_r
Las operaciones usadas arriba son parte de las operaciones aritméticas usuales predefinidas
en Octave (Ver Tabla 1.2). ¿Cuál es el orden de operaciones que efectúa la computadora en la
siguiente expresión?
Símbolo Significado
+ Adición
- Sustracción
* Multiplicación
/ División
^ Exponenciación
Nivel Operaciones
1 Las expresiones dentro de todos los paréntesis son evaluadas, comenzando del
más interno hacia afuera.
2 Todas las expresiones exponenciales son evaluadas, comenzando de izquierda
a derecha.
3 Todas las multiplicaciones y divisiones son evaluadas, de izquierda a derecha.
4 Todas las adiciones y sustracciones son evaluadas, de izquierda a derecha.
¿Por qué la diferencia en los tres métodos? Es más, los métodos 1 y 2 deberían darnos la misma
respuesta, ya que representan el mismo valor en aritmética exacta. Resulta que la computadora
realiza otro tipo de aritmética, llamada aritmética punto flotante o aritmética computacional,
la cual conlleva a errores, dado que no todo número real puede representarse exactamente en
la computadora.
Tipos de Errores
Cuando usamos la computadora hay que tener en cuenta los tipos de errores que debemos
minimizar, con la finalidad de poder confiar en los resultados que nos dé la computadora. Son
dos los tipos de errores:
Error de redondeo: Ocurren debido a que las computadoras tienen una capacidad limitada
para representar exactamente un número. Por ejemplo, el número irracional π.
R ≤ xc
Mínimo valor = f (R )
L ≤ xc ≤ R
Mínimo valor = f ( x c )
xc ≤ L
Mínimo valor = f (L)
Si R < x c
Imprimir f (R) y R
sino si L ≤ x c ≤ R
Imprimir f (x c ) y x c
sino
Imprimir f (L) y L
fin
>> a = 5 < 8;
>> a
a =
1
Cuando los operadores de relación son usados entre dos operandos numéricos siempre nos dan
como resultado un valor lógico, verdadero (1) o bien falso (0). Es importante mencionar ya desde
ahora que debemos tener cierto cuidado al usar los operadores == y ~= al comparar dos valores
numéricos. Esto se debe a los errores de redondeo al aproximar números reales. Estudiemos
el siguiente ejemplo
>> x = 0;
>> y = sin ( pi ) ;
>> x == y
ans =
0
Esto nos dice que sen(π) 6= 0 según la computadora. ¿A qué se debe esto? Si mostramos en
pantalla el valor de sen(π) según Octave obtendremos 1.2246 × 10−16 , lo cual es muy pequeño
y cercano a cero, pero no es exactamente cero. Esto se debe a que la función seno no es evaluada
en el valor exacto de π sino en una aproximación decimal de este número en la computadora,
con un número máximo de cifras significativas. Recordar que al ser π un número irracional,
no puede representarse con un número finito de cifras decimales, ni como el cociente de dos
enteros.
Ahora bien, dado que pedir igualdad exacta entre dos valores reales no es recomendable
¿cómo verificar igualdad entonces? Se sugiere mejor verificar una proximidad cercana. Por
1.2. Fundamentos de Programación 11
ejemplo, podríamos asumir que x y y son iguales en la computadora si la distancia entre ellos
es menor que 10−14 . Esto lo digitamos así
A continuación presentamos los operadores booleanos o lógicos. Estos operan sobre uno o
dos operandos lógicos (proposiciones) y conducen a un resultado lógico. Existen cinco operado-
res binarios lógicos: Y (& y &&), O inclusiva (| y ||), y O exclusiva (xor); y un operador lógico
unitario: NO (~), véase la Tabla 1.4. Observemos que existen dos versiones para los operadores
Y y O inclusivo. ¿Cuándo es usada la versión con atajo en evaluación? Para responder esto de-
bemos recordar la tabla de verdad de estos operadores y tener en cuenta que este tipo de atajo
solo se usa entre expresiones lógicas 1 × 1 ó escalares13 (véase la Tabla 1.5). Es claro que las
versiones con atajo tienen la misma tabla de verdad, pero la conveniencia radica en que a veces
no necesitamos verificar el valor de verdad de una expresión para obtener el resultado lógico de
verdadero o falso.14 En la siguiente tabla se ha puesto un signo de interrogación en los lugares
donde la computadora no necesita averiguar el valor de verdad de la segunda proposición:
x y x && y x y x||y
0 ? 0 0 0 0
0 ? 0 0 1 1
1 0 0 1 ? 1
1 1 1 1 ? 1
13
Cuando expresiones lógicas están dentro de un arreglo (array, en inglés) no escalares, los operadores lógicos
solo podrán usarse componente a componente. Comprenderemos mejor esta aseveración más adelante.
14
Si analizamos la Tabla 1.5 observamos que para el conectivo lógico Y, el resultado lógico sólo es verdadero (1)
si ambas proposiciones x y y son verdaderas, en los demás casos es falso (0), mientras que para el conectivo O
inclusivo el resultado sólo es falso si ambas proposiciones son falsas.
12 Capítulo 1. Introducción a Octave
fL = L ^2 + b * L + c ;
fR = R ^2 + b * R + c ;
fxc = xc ^2 + b * xc + c ;
if R < xc
fprintf ( ' Valor m í nimo f ( R ) = %5.2 f \ n ', fR ) ;
fprintf ( ' alcanzado en R = %5.2 f \ n ' ,R ) ;
elseif L <= xc && xc <= R
fprintf ( ' Valor m í nimo f ( xc ) = %5.2 f \ n ' , fxc ) ;
fprintf ( ' alcanzado en xc = %5.2 f \ n ', xc ) ;
else
fprintf ( ' Valor m í nimo f ( L ) = %5.2 f \ n ', fL ) ;
fprintf ( ' alcanzado en L = %5.2 f \ n ' ,L ) ;
end
En este último bloque de código hemos visto cómo se utiliza la construcción if-elseif. En
general toma la siguiente forma:
1.2. Fundamentos de Programación 13
es el más grande de los dos valores, obtenidos al evaluar las expresiones. La función min
trabaja de manera similar. Ambas funciones se pueden aplicar a una lista de dos o más
expresiones.
floor, ceil, round: Estas son funciones que son aplicadas a números reales para obtener
valores enteros cercanos. Así, para un número decimal x, tenemos que floor(x) nos da
el mayor número entero menor o igual que x, ceil(x) nos da el menor número entero
mayor o igual que x, y round(x) nos da el número entero más cercano a x. En caso x esté
localizado exactamente entre dos enteros, round(x) nos dará el mayor de los enteros. Por
ejemplo, round(4.5) nos da 5.
rem: Si x y y son enteros positivos, entonces rem(x,y) es el resto de dividir x por y. Por ejem-
plo, rem(23,3) nos da 2. La función rem también puede aplicarse a números reales de
cualquier signo.
5
c = ( f − 32),
9
donde f es una temperatura dada en ◦ F y c es la temperatura convertida a ◦ C. Escriba un
script que pida una temperatura en ◦ F, haga la conversión a grados Celsius y exhiba en
pantalla esta temperatura.
2) Un elipsoide, tal como nuestro planeta Tierra, se obtiene al rotar una elipse alrededor de
su eje menor. Se sabe que el radio ecuatorial de la Tierra es aproximadamente 21 km más
largo que su radio polar. El área superficial de un elipsoide está dado por15
2
à ¡ ¢ ¶!
r cos γ
µ
2
A ( r 1 , r 2 ) = 2π r 21 + ln
sen(γ) 1 − sen(γ)
r2
µ ¶
γ = arc cos .
r1
Asumimos r 2 < r 1 . Escriba un script que lea los radios ecuatorial y polar y exhiba en pan-
talla A ( r 1 , r 2 ) y la aproximación
r1 + r2 2
µ ¶
4π .
2
Aplique el script a los datos terrestres ( r 1 , r 2 ) = (6378.137, 6356.752). Exhiba suficientes
dígitos para mostrar la discrepancia entre la fórmula exacta y la aproximación.
15
Recordar que Octave está programada en inglés, y por ende, la función seno es representada por sin. Además,
la función logaritmo natural, escrita comúnmente como ln( x), es escrita en Octave como log(x).
1.2. Fundamentos de Programación 15
Si r = a = b entonces esto define una circunferencia cuyo perímetro está dado por P = 2π r .
Desafortunadamente, si a 6= b entonces no hay una fórmula simple para el perímetro y
debemos recurrir a una aproximación. Se conocen varias posibilidades:16
3h
µ ¶
P 1 = π( a + b ) P 5 = π( a + b ) 1 + p
10 + 4 − 3 h
p 64 − 3 h2
P2 = π 2(a2 + b2 ) P 6 = π( a + b )
s 64 − 16 h
(a − b)2 256 − 48 h − 21 h2
P3 = π 2(a2 + b2 ) − P 7 = π( a + b )
2 256 − 112 h + 3 h2
p
h 2 3− 1−h
µ ¶ µ ¶
P 4 = π( a + b ) 1 + P 8 = π( a + b )
8 2
Aquí,
¶2
a−b
µ
h= .
a+b
Escriba un script que solicite a y b e imprima en pantalla los valores P1 , . . . , P8 en una
manera que facilite la comparación. Los valores de h también deben ser exhibidos. Intente
los siguientes valores de entrada
¿Qué puede afirmar acerca de las diferencias entre las fórmulas del perímetro cuando la
elipse se vuelve más ovalada en forma?
4) Suponga que el valor de x es un entero positivo. Escriba una expresión booleana que es
verdadera si x es divisible por 2, 5 y 7.
q( x) = ax3 + bx2 + cx + d, a 6= 0.
Decimos que q es simple si sus tres raíces son reales y distintas. Decimos que q es monótona
si es siempre creciente o bien siempre decreciente. Como ejemplo, consideremos
q 1 ( x) = ( x − 1)( x − 2)( x − 3) = x3 − 6 x2 + 11 x − 6
q 2 ( x) = ( x − 1)( x − 2)( x − 3) + 100 = x3 − 6 x2 + 11 x + 94
q 3 ( x) = − x( x2 + 1) = − x3 − x
16
Véase http://www.mathsisfun.com/geometry/ellipse-perimeter.html
16 Capítulo 1. Introducción a Octave
bucle for: Es una construcción que permite repetir un bloque de código un número determi-
nado de veces. La repetición está controlada por los valores que toma el indice. Su forma
más simple es:
Es posible usar un bucle for dentro de otro. La necesidad de esto se verá más adelante.
bucle while: Es una construcción que permite repetir un bloque de código un número inde-
terminado de veces, hasta que se cumpla cierta condición. Toma la forma
Cada vez que se repite el bloque de código el programa verifica si la condición sigue
siendo verdadera. Esto implica que dentro de este bloque debe existir alguna expresión
que llegará a cambiar el valor de verdad de la condición.
Ilustraremos el uso de estos tipos de bucle con los siguientes problemas resueltos.
N
ρn =
n2
Inicializar : N1 = 0
Repetir para filas 1 hasta la n
Calcular el n ú mero de baldosas sin cortar en la fila .
Añ adir este n ú mero a N1 .
Poner ρ n = 4N1 /n2 .
Dado que sabemos el número de veces que se va a repetir nuestro programa, utilizaremos
un bucle for. Refinamos nuestro seudocódigo así:
Ahora nos concentramos en cómo calcular el número de baldosas sin cortar en la fila k. En la
Fig. 1.2 recordemos que el origen (0, 0) se encuentra en la esquina inferior izquierda. El punto
18 Capítulo 1. Introducción a Octave
(0, 1) (relativo a la fila 1), se encuentra obviamente encima del origen. La recta horizontal que
pasa por (0, 1), esto es, y = 1, interseca a la circunferencia en el punto
³p ´
n 2 − 12 , 1 .
Supongamos que ( h, 1) son las coordenadas del extremo superior derecho del último cuadradito
de la fila 1 que deseamos saber si es cortado o no por la circunferencia x2 + y2 = n2 . Recuérdese
que h es un número entero positivo. Para que este último cuadradito sea considerado como
baldosa sin cortar, debe suceder que
p
h ≤ n 2 − 12 ,
Ahora pensemos en cómo calcular N1 . Antes del bucle for debemos inicializar N1 = 0. Para
actualizar este valor dentro del bucle for basta escribir
N1 = N1 + h
Esta sentencia se lee “el valor de N1 se actualiza con el valor que resulte de calcular N1 + h”.
Es importante recordar que el símbolo = no significa igualdad cuando programamos en Octave.
Resumiendo, formamos el siguiente pedazo de código
Aquí, la variable k, llamada índice del bucle, toma valores del 1 al 10:
1.3. Bucles For y While 19
>> k = 1:10
k =
1 2 3 4 5 6 7 8 9 10
Podemos cambiar el conjunto de valores que toma el índice proveyendo un incremento, por
ejemplo
>> k = 1:2:10
k =
1 3 5 7 9
nombre_arreglo = valor_inicial:incremento:valor_final
Aquí, el incremento puede ser cualquier número real positivo y asumimos que el valor_inicial
es menor o igual que el valor_final. Estos valores pueden ser números decimales. Por ejemplo:
>> k = -2.35:1.4:4.5
k =
-2.3500 -0.9500 0.4500 1.8500 3.2500
Si el valor_inicial es mayor que el valor_final obtenemos un arreglo vacío. Por otro lado,
es posible también usar un decremento si deseamos un arreglo ordenado en forma decreciente:
nombre_arreglo = valor_inicial:decremento:valor_final
n = 10000
ro_n = 3.14119052
error = 0.00040213
n 2π
µ ¶
A n = sen ,
2 n
π
µ ¶
B n = n tan ,
n
Usando la Fig. 1.3 para guiarnos, podemos deducir que el promedio de las dos áreas poligo-
nales
A n + Bn
ρn =
2
es una aproximación de π, con error absoluto que satisface
¯ρ n − π ¯ < B n − A n .
¯ ¯
( B m − A m ) ≤ δ.
n = 10;
for k = 1:8
A_n = ( n /2) * sin (2* pi / n ) ;
1.3. Bucles For y While 21
B_n = n * tan ( pi / n ) ;
ro_n = ( A_n + B_n ) /2;
n = 10* n ;
end
Los valores de ensayo son n = 10, 102 , 103 , . . . , 108 . Si añadimos más líneas de código para im-
primir en pantalla, conseguimos:
Un bucle for no puede ser usado porque debemos saber el número de iteraciones por ade-
lantado y esto es justo lo que buscamos. Un mecanismo alternativo para iterar es el bucle while.
Su uso en el seudocódigo anterior se implementa en Octave como sigue:
Si la expresión lógica CotaError > delta es verdadera, entonces el cuerpo del bucle es
ejecutado. Esta ejecución se repetirá hasta que la expresión lógica sea falsa. Cuando el bucle
termina de ejecutarse, el programa continuará ejecutando las líneas debajo de la palabra end.
Debemos tener presente que variables que sean utilizadas por el bucle while deben iniciali-
zarse antes de comenzar el bucle.
La solución final del problema es presentada en el siguiente script.
Observemos que la condición al inicio del bucle while en un principio es verdadera (caso
contrario no se ejecutaría iteración alguna), y basta que una de las proposiciones encerradas
entre paréntesis llegue a ser falsa para que el bucle termine. Si no se hubiese tenido el cuidado
de incorporar un número máximo de iteraciones (nMax) podría haberse incurrido en un bucle
infinito (esto ocurriría si damos, por ejemplo, un δ muy pequeño como 10−20 ). Recordar que
en caso el programa tarde mucho en exhibir el output, debe usarse Ctrl-c para abortar la
ejecución.
Para el input δ = 10−6 y nMax=104 obtenemos la siguiente salida
ro_m = 3.141592486963389
Pi = 3.141592653589793
break: Cuando es ejecutada la línea que contiene al comando break, el bucle es obligado a
terminar y el control del programa pasa a la línea de código ubicada después del fin (end)
del bucle.
continue: Cuando es ejecutado este comando el bucle vuelve a reiniciarse con el próximo valor
de la iteración.
3 x = 0;
4 for i =1:5
5 x = x + 1;
6 if i == 3
7 break ;
8 end
9 fprintf ( ' Para iteraci ó n i = %1d , el valor de x es %1 d \ n ',i , x ) ;
10 end
11 disp ( ' Este aviso aparece despu é s de terminado el bucle ') ;
12 fprintf ( ' El valor actual de x en memoria es %1 d \ n ' ,x ) ;
Queda como ejercicio justificar porqué el valor en memoria para x es 3. El siguiente programa
ilustra el uso del comando continue.
1000.
7) La implementación del programa 1.6 requiere la constante predefinida pi. Usando repeti-
damente las fórmulas de ángulo mitad
s s
1 + cos(θ ) 1 − cos(θ )
cos(θ /2) = , sen(θ /2) = ,
2 2
podemos evitar esta dependencia y producir un método genuino que “descubra” π. Observe
que el caso n = 3 involucra
p p
cos(π/3) = 1/2, sen(π/3) = 3/2, y sen(2π/3) = 3/2.
Las evaluaciones necesarias para coseno y seno para A 6 y B6 pueden ser obtenidas de es-
tos valores vía las fórmulas de ángulo mitad. Usando estas evaluaciones trigonométricas
actualizadas, podemos obtener los valores necesarios de coseno y seno para A 12 y B12 , etc.
Use esta idea para escribir un script que pida un número positivo δ > 10−12 y calcule un
estimado de π con un error menor que δ.
Primero ilustraremos cómo plotear una función más simple g( x) = sen( x) en el intervalo [0, 2π].
Debemos entender que la manera cómo funciona el ploteo en Octave (y en todos los software)
es dibujar en el plano un conjunto finito de puntos y luego unirlos con segmentos de recta. En
otras palabras, lo que se plotea en una computadora es realmente un camino poligonal. Sin
embargo, podemos “engañar” nuestra vista si ploteamos una cantidad suficiente de puntos.
Por ejemplo, grafiquemos la función seno con una cantidad insuficiente de puntos. Primero
construimos los puntos ( x, g( x)) almacenando las abscisas y ordenados en arreglos separados:
>> x = 0:2* pi
x =
0 1 2 3 4 5 6
>> y = sin ( x ) ;
Observar que la función seno se aplica componente a componente, y por ende el arreglo y es
del mismo tamaño que x. Para plotear los puntos y unirlos con segmentos de recta usamos el
comando plot
plot (x ,y ) ;
shg ; % show graph ( mostrar gr á fica )
El comando shg es usado para que la ventana de ploteo (titulada Figure 1), aparezca encima
de todas las ventanas abiertas (lo cual a veces no es necesario). El resultado de este ploteo se
muestra en la Fig. 1.4. Respondemos el problema con el siguiente script
function L = PolyLine (u , v )
% u y v son vectores columna ( n +1) x 1 , con u (1) = u ( n +1) y v (1) ←-
= v ( n +1) .
% L es el perimetro del poligono con vertices
% (u (1) ,v (1) ) , ... , ( u ( n ) ,v ( n ) )
alfa = sum(abs(z(1:4)-z(2:5)))
α = | z1 − z2 | + | z2 − z3 | + | z3 − z4 | + | z4 − z5 |
x2 + y2 ≤ 1.
Si tiramos n dardos (con n grande), entonces la fracción de tiros que tienen éxito debería
aproximar al cociente entre el área de la circunferencia y el área del cuadrado, esto es
4(Nro. de éxitos)
π= .
n
Escriba un script que simule el tiro de 10 000 dardos y escriba un estimado para π. Los dardos
deben estar uniformemente distribuidos sobre el cuadrado. ¿Qué sucede si los dardos están
predispuestos a caer cercano al origen? ¿Cómo afecta esto en la estimación de π?
Al ejecutar este script para n=10e4 y luego n=10e6 vemos que la probabilidad obtenida
concuerda muy bien con la longitud del intervalo [L, R ]. Para n=100 no se puede apreciar que
la distribución de los números en [L, R ] sea uniforme.
Una consecuencia de la distribución uniforme es que para n grande el comando rand elige
cualquier número entre 0 y 1 con igual probabilidad (la elección es insesgada).
La función rand puede ser usada para construir un vector de números aleatorios. Si n ∈ Z+ ,
entonces
r = rand (n ,1)
Para una mejor visualización construiremos un vector aleatorio de números enteros que varíen
del 1 al 10. Aquí, cada decil formaría los intervalos ]0, 1], ]1, 2], . . . , ]9, 10].
Si aumentamos a n=1e6 (un millón de repeticiones) obtenemos una gráfica de barras con al-
turas de casi el mismo tamaño. Esto nos dice que a mayor número de repeticiones el comando
rand nos da una distribución uniforme de números entre 1 y 10, incluyendo extremos. Así, cual-
quier entero entre 1 y 10 tiene igual probabilidad de ser elegido por el comando rand (luego de
haberlo reescalado, trasladado y aplicado el comando ceil).
Podemos concluir que una simulación aleatoria debe realizarse un gran número de
veces, caso contrario se corre el peligro de que no se cumpla una elección al azar con el tipo de
distribución elegida. En nuestro caso, al usar rand estamos usando una distribución uniforme.
Examine qué ocurre cuando ejecuta el script anterior con 20 o 100 repeticiones.
Algunos descriptores estadísticos de un conjunto de datos, más usuales, son:
• La media, que es el promedio de la data (Octave: mean).
• La desviación estándar, que mide el esparcimiento de la data alrededor de la media
(Octave: std).
1.5. Simulación Monte Carlo 31
El siguiente script resuelve el problema de tirar un dardo n veces sobre el cuadrado [−1, 1] ×
[−1, 1], sin sesgamiento, esto es, con distribución uniforme, para estimar el valor de pi.
Compilamos
NOTA: No digitar 1e9 porque Octave no soporta crear un vector de ese tamaño.
32 Capítulo 1. Introducción a Octave
Ahora apreciemos cómo está distribuida la data para n=1e4, borrando en el script anterior
los porcentajes al comienzo de las líneas 8 a la 15. Obtenemos la siguiente figura:
Ahora vamos a predisponer los dardos a que caigan cerca al origen. Para ello, usaremos una
distribución normal, lo cual se consigue con el uso del comando randn. La asignación
r = randn(n,1)
produce un vector columna n × 1 cuyas entradas siguen una distribución normal con media cero
y desviación estándar uno. El siguiente script exhibe el comportamiento de una distribución
normal para una muestra de 106 repeticiones, ploteando su histograma.
Al compilar obtenemos:
1.5. Simulación Monte Carlo 33
La distribución normal, en principio, nos puede dar cualquier número real, pero con mayor
probabilidad de que sea elegido un número cercano a la media, que lejos de ella.
El siguiente script implementa lanzamientos sesgados (con predilección a que los dardos
caigan cercanos al origen).
29 end
30 piEst = 4*( exitos / ncuad ) ;
31 fprintf ( ' Valor Est . de pi es : %11.9 f \ n ', piEst ) ;
32 fprintf ( ' Valor exacto de pi es : %11.9 f \ n ', pi ) ;