martes, 16 de noviembre de 2010

Lenguaje Funcional R (Problemas de Distribución)

Como ya sabemos R es un lenguaje funcional, es decir, es un lenguaje basado en funciones. Bueno en R hay demasiadas funciones, que son muy útiles y entre ellas encontré las funciones para calcular ciertas distribuciones que se ven en la materia de probabilidad y estadística, como lo son:
  • La Distribución Binomial.
  • La Distribución Hipergeométrica.
  • La Distribución Normal.
Las primeras dos distribuciones de probabilidad, están clasificadas por ser distribuciones discretas, es decir que la variable aleatoria toma valores enteros. Y la distribución normal esta clasificada por ser una distribución continua.

Bueno, la distribución de probabilidad, de una variable aleatoria es una función que asigna a cada suceso sobre dicha variable, la probabilidad de que este suceso ocurra.

Es muy sencillo aplicar las fórmulas de cada una de estas tres distribuciones a un problema, pero para poder entender lo que haré en R, hay que entender primero los datos de las fórmulas de cada Distribución y su solución escrita.

Bien, la Distribución Binomial, solo tiene dos resultados, el éxito y el fracaso. El éxito está representado por p y el fracaso por q. Se debe saber que una probabilidad esta dada de 0 a 1, es decir, una probabilidad no puede ser mayor a 1, ni menor a 0. Además p + q = 1, en donde 1 es la unidad (es la mayor probabilidad).

La fórmula para calcular la probabilidad binomial está dada por:
En donde:
X = es la variable aleatoria que sigue una distribución binomial.

x = es el valor que toma la variable aleatoria.

n = es el tamaño de la muestra.
C = combinaciones.p = probabilidad de éxito.
q = probabilidad de fracaso.


Bueno, ahora resolveré un problema de distribución binomial, mediante una explicación y mediante una función en R.

Problema de Distribución Binomial
El porcentaje de artículos defectuosos fabricados por una máquina es del 20%. En una muestra de 12 artículos seleccionados al azar, fabricados en esa máquina, encontrar o calcular las siguientes probabilidades:
a) de que ninguno sea defectuoso.
b) menos de 3 sean defectuosos.

c) más de 3 pero menos de 7 sean defectuosos.
d) como mínimo, 4 sean defectuosos.


a) De que ninguno sea defectuoso, esto dignifica que haya 0 artículos defectuosos, en este caso x toma el valor de 0 y calculamos esta probabilidad con el uso de la fórmula, es decir, solo sustituiremos los valores siguientes en la fórmula.

p(x = 0) = 0.0687
x = 0
p = 0.20 (esto es del 20%)
q = 0.80

n = 12


En R hay la función que te calcula la probabilidad binomial es pbinom(). Dentro de los () va x, n, p, es decir, (x, n, p).
Bueno para resolver este inciso en R, colocamos en la terminal R (si lo tenemos instalado), y después colocamos:
pbinom(0, 12, 0.20)
Y presionamos enter, y el resultado obtenido es: 0.06871948.
Aquí les muestro la imagen de este inciso.

b) Menos de 3 sean defectuosos, es decir, que solamente 2 sean defectuosos, entonces al utilizar la fórmula tendremos que obtener la probabilidad de x = 0, x = 1 y x =2 y sumando los resultados de cada una de estas probabilidades obtendremos la probabilidad de x = 2.

p(x < 3) = p(x = 0) + p(x = 1) + p(x = 2) = 0.0687 + 0.2061 + 0.2834 = 0.5582
p = 0.20 (esto es del 20%)
q = 0.80

n = 12

En R, es más sencillo realizar este inciso ya que en R la probabilidad de x número trae acumuladas las probabilidades de los números anteriores a el.

Es decir, en este inciso en R, no es necesario sumar las probabilidades de x = 0, x = 1 y x = 2 para obtener la probabilidad de que solamente hayan dos artículos defectuosos, si no que con solo obtener la probabilidad de x = 2, obtenemos la probabilidad de que hayan solamente 2 artículos defectuosos, ya que como les mencione en R la probabilidad de 2 trae acumuladas las probabilidades de 0, 1 y la del mismo 2.

Entonces en la terminal tecleamos:
pbinom(2, 12, 0.20)
Y presionamos enter y el resultado es: 0.5583457

Aquí esta la imagen del inciso.


c) Más de 3 pero menos de 7 sean defectuosos, esto quiere decir que solo 4, 5, ó 6 sean los artículos defectuosos. Entonces para obtener la probabilidad de esto, sumaremos las probabilidades de x = 4, x = 5 y x = 6.

p(3 < x < 7) = p(x = 4) + p(x = 5) + p(x = 6) = 0.1328 + 0.0531 + 0.0155 = 0.2014
p = 0.20 (esto es del 20%)
q = 0.80

n = 12


En R, a la probabilidad de x = 6 se le restará la probabilidad de x = 3, ya que esta contiene acumuladas las probabilidades de x = 0 a x = 3 y solo se quiere la probabilidad de 4 a 6. De la resta resultará la probabilidad de 6, que trae acumuladas las probabilidades de x = 4 a x = 6.
En R escribimos lo siguiente:
pbinom(6, 12, 0.20) - pbinom(3, 12, 0.20)
Presionamos enter y obtenemos: 0.2015279
Aquí les muestro la imagen de este inciso.

d) Como mínimo, 4 sean defectuosos, esto significa que 4 o más sean defectuosos. Entonces sumaremos las probabilidades de x = 0, x = 1, x = 2 y x =3 y la suma de estas probabilidades las restaremos a la unidad, es decir a 1, y el resultado será la probabilidad de que hayan 4 ó más artículos defectuosos.

p(x < = 4) = 1 - [p(x = 0) + p(x = 1) + p(x = 2) + p(x = 3)] = 1- [0.0687 + 0.2061 + 0.2834 + 0.2362] = 0.2056
p = 0.20 (esto es del 20%)
q = 0.80

n = 12

En R, a la unidad, es decir, a 1 se le restará la probabilidad de x = 3, ya que queremos la probabilidad de x = 4 en adelante, entonces el resultado de la resta, será dicha probabilidad.

Escribimos en la terminal:
1 - pbinom(3, 12, 0.20)
Presionamos enter y obtenemos: 0.2054311

Aquí esta la imagen de este inciso en la terminal.


Y aquí se encuentra la imagen con todos los incisos.


Ahora les explicaré sobre la Distribución Poisson.
Las probabilidades de esta distribución ocurren dentro de un intervalo de tiempo o espacio, y además se obtienen mediante la fórmula:
En donde:
X = variable aleatoria que sigue una distribución Poisson.
x = valor que toma la variable aleatoria.
μ = media de la distribución (número promedio de éxitos dentro del intervalo de tiempo o espacio de interés).
e = base de los logaritmos naturales (2.7182).

μ
= λ t
λ
= razón media.
t = intervalo de tiempo o espacio.

Ahora resolveré un problema de distribución de Poisson mediante su fórmula puntual y mediante una función en R.

Problema de Distribución de Poisson
En el estudio de un cableado eléctrico se encontró que tiene en promedio 3 fallas por Km. Determine las siguientes probabilidades:
a) encontrar mas de una falla en los primeros 500 metros.
b) menos de dos fallas en 2 kms
c) mas de 3 fallas en 1 Km
d) de que sean exactamente 3 fallas en 2 kms

a
) Encontrar mas de una falla en los primeros 500 metros (0.5 Kms). Para encontrar esta probabilidad, a la unidad, es decir a 1 se le restará la probabilidad de x = 0, ya que se quiere la probabilidad de 1 en adelante. Calculamos la probabilidad de x = 0 en la fórmula, sustituyendo valores.

p(x < = 1) = 1 - p(x < = 0) = 1 - 0.2231 = 0.7769
μ
= λ t
λ = 3 fallas / Km
μ = 3 fallas /Km * .5 Km = 1.5 fallas

En R, la función para calcular la probabilidad de Poisson es ppois(). Dentro de los () van x,
λ, es decir, (x, λ).
También en la terminal haremos lo mismo, es decir se le restará la probabilidad de x = 0 a la unidad, es decir, a 1.

Escribimos en la terminal:
1 - ppois(0, 1.5)
Y presionamos enter y obtenemos: 0.7768698

Y aquí esta la imagen de este inciso.

b) Menos de 2 fallas en 2 Kms. Esto significa que solo se encuentren 1 ó 0 fallas. Calcularemos la probabilidad de x = 0 y la probabilidad de x = 1 y sumaremos las dos probabilidades, y ese será el resultado.

p(x < 2) = p(x < = 1) = p(x = 0) + p(x = 1) = 0.0024787 + 0.01487 = 0.0173487
μ = λ t
λ = 3 fallas / Km
μ = 3 fallas /Km * 2 Km = 6 fallas

En R, como les mencione, la probabilidad de x número trae acumuladas las probabilidades de todos los número anteriores a x número, entonces para este inciso solo en R solo se calcularé la probabilidad de x = 1, ya que esta trae acumulada la probabilidad de x = 0.
Escrbimos en la terminal:
ppois(1, 6)
Presionamos enter y obtenemos: 0.01735127


Aquí esta la imagen de este inciso en la terminal.

c) Mas de 3 fallas en 1 Km, esto significa que hayan 3 fallas o mas. Entonces, obtendremos mediante la fórmula las probabilidades de x = 0, x = 1, y x = 2, las sumaremos y la suma de estas probabilidades la restaremos a la unidad, 1, ya que solo queremos la probabilidad de 3 en adelante.

p(x < = 3) = 1 - [p(x = 0) + p(x = 1) + p(x = 2)] = 1 - [0.04978 + 0.1493 + 0.2240] = 0.57692
μ = λ t
λ = 3 fallas / Km
μ = 3 fallas /Km * 1 Km = 3 fallas

En R, solo le restaremos a 1 la probabilidad de x = 2. Tecleamos lo siguiente en la terminal:
1 - ppois(2, 3)
Presionamos enter y obtenemos: 0.5768099

Aquí les coloco la imagen de este inciso.

d) De que sean exactamente 3 fallas en 2 Kms, esto significa de que solamente hayan 3 fallas, entonces calcularemos con la fórmula la probabilidad de x = 3.

p(x = 3) = 0.08923
μ = λ t

λ = 3 fallas / Km

μ = 3 fallas /Km * 2 Km = 6 fallas


En R, a la probabilidad de x = 3 tenemos que restarle la probabilidad de x = 2, para obtener solamente la probabilidad de que se encuentren 3 fallas en 2 Km. Escribimos lo siguiente en la terminal:
ppois(3, 6) - ppois(2, 6)
Presionamos enter y el resultado es: 0.08923508

Aquí les muestro la imagen de este inciso.


Y aquí les coloco la imagen con todos los incisos.

Bueno ahora les explicaré sobre la distribución normal.

La Distribución Normal es una de las distribuciones mas importantes, además es una curva en forma de campana (campana de Gauss).
En probabilidad y estadística se resuelven problemas como de encontrar una probabilidad en una cierta area de la gráfica que como les mencione dicha gráfica de la distribución normal es una curva en forma de campana.

Para encontrar la probabilidad en una cierta area de la curva, se necesitan tener los siguientes datos:

x = variable de la distribució normal
μ = media
σ = desviación estándar

Bueno, estos datos se utilizan para obtener z, que es una variable tipificada de x, la cual sigue tambien una distribución normal, pero donde μ = 0 y σ = 1.

Al obtener z mediante la fórmula:
nos vamos a unas tablas de distribución normal, que dependiendo del valor de z será la probabilidad de x. Las tablas traen diferentes probabilidades para diferentes valores de z. Pero la forma de resolver el problema para encontrar la probabilidad en una cierta area dependerá directamente de lo que el problema dicte.

Ahora resolveré un problema de distribución normal mediante la fórmula de z junto con las tablas de distribución normal y también mediante una función en R.

Problema de Distribución Normal
El tiempo de ensamble de un juguete se distribuye en forma normal con una media de 14.5 minutos y una desviación estándar de 2.5 minutos. Cuál es la probabilidad de que este tipo de juguete se pueda ensamblar:
a) en menos de 12 minutos
b) entre 10 y 15 minutos
c) en mas de 8 minutos

a) En menos de 12 minutos. En las tablas de la distribución normal, la probabilidad de x número (al igual que en R), trae acumuladas las probabilidades de los todos los números anteriores a x número. Aquí se nos pide obtener la probabilidad de que el tiempo de ensamble de un juguete sea en menos de 12 minutos, entonces obtendremos el valor de z mediante su fórmula, en donde x será 12 y al obtener el valor de z, checaré la probabilidad para dicho valor de z en las tablas, y en este caso, esa será la probabilidad de que sea en menos de 12 minutos.

p(x < = 12) = p(z < = -1) = 0.1587
μ = 14.5 minutos
σ = 2.5 minutos
z = -1

En R, la función para obtener una probabilidad normal es pnorm(), y dentro de los (), va x, μ, σ, es decir, (x, μ, σ). Entonces en nuestra termninal en este caso teclearemos lo siguiente:
pnorm(12, 14.5, 2.5)
Presionamos enter y el resultado es: 0.1586553

Aquí les muestro la imagen de este inciso en la terminal.


b) Entre 10 y 15 minutos, en este caso obtendremos dos valores de z, uno para x = 10 y otro para x = 15. Después checaré en la tabla el valor de z para x = 10 y el valor de z para x = 15, y a la probabilidad de x = 15 le restaré la, probabilidad de x = 10, ya que solo queremos la probabilidad entre 10 y 15.

p(10 < = x < = 15) = p(-1.8 mayor igual z menor igual 0.2) = 0.5793 - 0.0359 = 0.5434
μ = 14.5 minutos
σ = 2.5 minutos
z = -1.8
p(x = 10) = 0.0359
z = 0.2
p(x = 15) = 0.5793

En R de la misma manera a la probabilidad normal de x = 15, le restaremos la probabilidad normal de x = 10, entonces escribimos lo siguiente en la terminal:
pnorm(15, 14.5, 2.5) - pnorm(10, 14.5, 2.5)
Presionamos enter y el resultado es: 0.5433294

Ahora aquí les muestro la imagen en la terminal de este inciso.

c) En mas de 8 minutos, esto significa que a la unidad, 1, le restaremos la probabilidad de x = 8, ya que lo que resulte será la probabilidad de 8 en adelante.
Entonces obtenemos el valor de z y checaré el valor de z en las tablas de distribución normal para ver cual será la probabilidad y teniendo esta probabilidad, ahora si se la resto a 1.

p(x < = 8) = p(z < = -2.6) = 1 - 0.0047 = 0.9953
μ = 14.5 minutos
σ = 2.5 minutos
z = -2.6
p(x = 8) = .0047

En R, haremos lo mismo, es decir, a la unidad, 1, le restaremos la probabilidad de 8. Entonces, escribimos en la terminal lo siguiente:
1 - pnorm(8, 14.5, 2.5)
Presionamos enter y obtenemos: 0.9953388

Aquí les muestro la imagen de este inciso en la terminal.

Y aquí les muestro la imagen de la terminal con todos los incisos de este problema.


Referencias.
Funciones de Distribución en R
Los problemas los obtuve de la materia que llevo de Probabilidad Estocástica.
La tabla de distribución normal, la pueden ver aquí

Saludos.


lunes, 15 de noviembre de 2010

Lenguajes funcionales (Reporte #4)

Los lenguajes funcionales, son los lenguajes basados en el uso de funciones, entre ellos se encuentran, los lenguajes R, Scheme, Haskell, Miranda, Erlang, Lisp, etc.

Lenguaje Funcional R
R es un lenguaje que tiene muchas funciones para lo que son análisis estadísticos y gráficos
.
Es un buen lenguaje para realizar gráficas, de tipo: histogramas, circulares, de líneas, etc.

El programa que realice en R, es una gráfica con ciertas características, que más adelante les explicare. Este programa se basa en ciertos datos, de un problema de probabilidad y estadíca; además de la gráfica, obtuve las medidas de tendencia central, las cuales son, la media, la mediana y la moda (en este caso, solo obtuve la media y la mediana). Además obtuve también la varianza y la desviación estándard, que son las medidas de dispersión. Esto, como ya lo mencione es de un problema de probabilidad; de alli me base para realizar la gráfica y las diferentes medidas en R.

Problema
Se listan los precios de 19 marcas diferentes de zapatos para caminar. Construya una gráfica para mostrar la distribución de los datos.
90, 70, 70, 70, 75, 70
65, 68, 60, 74, 70, 95
75, 70, 68, 65, 40, 65
70
Bueno, si ya tenemos instalado R, en nuestra terminal escribibimos R, y nos aparecerá un símbolo como este >, lo cual significa que ya podemos comenzar a realizar la gráfica. Colocaremos lo que en la imagen les muestro:

En R, la asignación de un valor a una variable, se hace asi: a <- 5, en donde a es la variable y 5 es el valor que se le asigna a la variable a. Bueno, como vemos en la imagen, escribi Marcas <- 1:19, esto indica que Marcas tiene un rango de 1 a 19, ya que 19 son el número de datos que tenemos. En R, para asignar varios datos a una variable, se hace asi: a <- c(4, 5, 6). Es por esto que después escribi Precios <- c(90, 70, 70, 70, 75, 70, 65, 68, 60, 74, 70, 95, 75, 70, 68, 65, 40, 65, 70). Después escribi plot(Marcas, Precios), esto es para que se realice la gráfica de distribución de Marcas y Precios. Al colocar esto, se muestra una ventana con la gráfica siguiente:

Como vemos, solo se muestra la distribución de los datos de Marcas y Precios; Marcas se encuentra en el eje de las x y Precios en el eje de las y, esto sucede al haber escrito plot(Marcas, Precios), ya que si hubiera escrito plot(Precios, Marcas), entonces Marcas estaría en el eje de las y y Precios en el eje de las x; en si para realizar una gráfica se utiliza así la función: plot(x,y).

Hay una función en R que permite ordenar los datos en orden ascendente y otra función que permite ordenarlos en orden descendente. Dichas funciones son, sort() y rev(sort()) respectivamente.
A continuación les muestro la imagen en donde use estas funciones, solo para que se muestre como quedan los datos de Precios ordenados ascendente y descendentemente.

Después le agregue ciertas características a la gráfica como lo son, las figuras que se muestran, el color del relleno de las figuras, el color del contorno de dichas figuras, el título de la gráfica, el estilo de dicho título, y el ancho del contorno de las figuras. La imagen siguiente, muestra lo que escribi para realizar la gráfica con las características que les mencione.

Como vemos se muestra que escribi sort(Precios), que es como les mencione anteriormente, para ordenar los datos de Precios, en forma ascendente (para verlos asi en la gráfica). Utilice pch = 21, para elegir la el símbolo o figura que quiero que se muestre en la gráfica, en este caso escogí el número 21 del cuadro siguiente:

Después utilice bg = 619, para determinar el color de relleno de los símbolos. El número del color que se desea poner al relleno de los símbolos, se encuentra, escribiendo en la termial (estando dentro de R), colors(), y así se despliegan todos los números de los colores junto con el nombre del color (hay 657 colores). Después escribi col = 644, esto indica el color del contorno de los símbolos, que igualmente el número del color se obtiene al escribir colors() en la terminal. También se puede escribir el nombre del color en vez del número de este, por ejemplo, col = "red". Vemos que después escribi main = "Distribución de precios y marcas", main indica el título que queremos que se muestre en nuestra gráfica, el cual deberá ir entre comillas. Después escribi font.main = 4, font.main controla el estilo del título. Si colocamos el 1 es para que el texto del título se vea normal, el 2 es para que se vea en negritas, el 3 para que se vea en cursiva y el 4 para que el texto del título de vea en negritas y cursiva. En este caso escogí el 4. Y por último escribí lwd = 1, que esto indica la anchura del contorno de los símbolos, en este caso le puse 1. Sí le hubiese puesto 2, simplemente, el ancho del contorno de los símbolos aumenta. Y aquí les muestro como quedó la gráfica, ya con las características anteriores.


Ahora les explicaré como obtuve las medidas de tendencia central y la varianza y la desviación estándard de los datos del problema.

Bueno ahora les mostraré la imagen en donde calculo la media, que la media es el promedio de los datos, es decir la suma de todos los datos sobre el número total de datos.

Como vemos escribi Media <- sum(Precios)/Marcas. Utilice la función sum(), ya que realiza la suma de todos los datos que se encuentren, en este caso en Precios. Después esa suma la dividí entre Marcas, y luego escribi Media, esto es para imprimir lo que resulta de la operación que se le asigno a Media, y de esta manera se obtuvieron varios resultados, siendo el último de ellos, la Media, que es 70. Todos los demás resultados que se obtuvieron, fue porque dividi entre Marcas es decir, se realizaba la suma de los datos de Precios y se iba dividiendo esa suma entre 1, entre 2, entre 3, hasta llegar al 19. Pero otra manera más directa que realice para calcular la Media, fue, como lo vemos en la imagen, Media <- sum(Precios)/19, y asi escribiendo después Media, se imprime directo el resultado de esta, (que es 70), ya que se dividió directamente entre el número total de datos, es decir 19.

La varianza representa la variación que tienen los datos respecto a la media.
Normalmente se calcula asi:

Donde Xi, representa a cada uno de los datos, () representa la media, y n representa el total de datos que se tienen en una muestra.

La desviación estándard es el promedio de la distancia que hay de cada dato con respecto a la media. Normalmente se calcula así: Es decir, la desviación estándar es la raíz cuadrada de la varianza.

Ahora, les coloco la imagen en donde se muestran las funciones que utilice para obtener la varianza y la desviación estándard.


Como vemos, es sencillo calcular la varianza y la desviación estándard, ya que solo se utilizan funciones. Para calcular la varianza se utiliza la función var() y para calcular la desviación estándard se utiliza la función sd(). En este caso escribi var(Precios) y sd(Precios), para que se calcularán la varianza y la desviación estándard de los datos que se asignaron a Precios siendo la varianza igual a 120.7778 y la desviación estándar igual a 10.98989.

La mediana es el dato central que se encuentra en un conjunto de datos ordenados en forma ascendente.
En este caso la mediana es 70, ya que tenemos 19 datos, entonces ordenamos estos datos en forma ascend
ente y nos vamos al dato que se encuentra en el centro, es decir el dato #10. y vemos que este dato es el 70. Si el número total de datos hubiera sido 20, entonces la mediana seria la suma del dato 10 y del dato 11 sobre 2.

Y ya por último les coloco la imagen en donde se muestra la función que se utiliza para calcular la mediana y además también en esta imagen se muestra una fución que hay en R para calcular la media, aunque esta ya la realice anteriormente pero sin el uso de esta función.

Como vemos la función que se utiliza para calcular la mediana, es median() y para calcular la media es mean(). En este caso escribi, median(Precios) y mean(Precios), para obtener la mediana y la media de los datos asignados a Precios, siendo la mediana igual a 70 y la media igual a 70 como lo mencione anteriormente.

Lenguaje Erlang
Erlang es otro lenguaje funcional, que tiene una característica, que se dice que es la mayor fortaleza de este lenguaje, la cual es la concurrencia, que es cuando se llevan a cabo o se ejecutan varios threads (procesos) al mismo tiempo.

Los archivos en Erlang tienen la extensión .erl
Los programas en Erlang contienen funciones junto con su aridad. La aridad es el número de datos de entrada que la función permitirá que el usuario ingrese.
Las funciones se exportan en el programas de la manera siguiente: -export(nombre_función/aridad).

Realice tres programas en Erlang sencillos, uno de ellos calcula la potencia y esta en forma recursiva, el otro realiza las diferentes operaciones básicas (suma, resta, multiplicación y división), con el uso del case, y de acuerdo a la opción que el usuario eliga, será la operación que se realizará y el otro calcula las areas de diferentes figuras geométricas (cuadrado, triángulo, rombo, trapecio, círculo y rectángulo).

El primer programa que les mostraré, lo llame potencia.erl y como ya lo mencione anteriormente calcula potencia en forma recursiva.

Código
-module(potencia).
-export([pot/2]).

pot(N, K) when K == 0 -> 1;
pot(N, K) when K > 0 -> N*pot(N, K-1).
En esta parte:
-module(potencia).
-export([pot/2]).
Se colocan en el programa el módulo y la función que se utilizará. El nombre del módulo, deberá ser el mismo nombre que el del programa, en este caso es potencia. La función que utilice en este programa la llame pot y su aridad es de 2, es decir el usuario solo podrá ingresar dos datos de entrada en esta función.
Al final de colocar el módulo y la funcion o funciones se colocará un punto .

En esta otra parte:
pot(N, K) when K == 0 -> 1;
pot(N, K) when K > 0 -> N*pot(N, K-1).
Vemos que escribi pot(N, K), bueno esta es la función pot que contiene a las variables N y K, siendo N el número al cual se le calculará la potencia y K la potencia.

Las variables en Erlang van en mayúscula.

Sabemos que todo número elevado a la 0 es 1, es por eso que coloque la función when con la condición de que cuando K == 0, enonces el resultado que se imprimirá será 1.
Y ya después coloque nuevamente la función de when con la condición de que cuando K > 0, entonces se calculara la potencia de forma recursiva.
Vemos que al final de la instrucción de la potencia recursiva, se coloca un .
Hay que poner mucha atención en la sintaxis cuando se utilizan las funciones if, when, y case.

Para ejecutar este programa, colocamos primreamente erl en nuestra terminal y después escribimos lo siguiente:
c(potencia).
Donde potencia es el nombre del programa. Y como el programa esta correcto, en la terminal se mostrara: {ok,potencia}. Y ahora si se puede realizar la potencia K de un número N. Esto es de la siguiente manera: se coloca primero el nombre del programa y después : y luego se escribe el nombre de la función, que en este caso es pot y seguido de la función se colocan entre paréntesis N y K y al final un punto . Aquí les muestro la imagen de la ejecución de este programa, comprobando los casos de K == 0 y K >0.


Ahora les colocaré el código del programa que realiza las operaciones básicas con el uso del case, en donde se elige la opción de la operacón a realizar. Ese programa lo llame opc.erl.

Código
-module(opc).
-export([opciones/3]).

opciones(N, A, B) ->
case N of
1 -> A+B;
2 -> A-B;
3 -> A*B;
4 -> A/B;
N when N > 4 -> "Ingresa otra opcion (1-4)"
end.
Ahora, este programa como lo mencione anteriormente, realiza las operaciones básicas, pero utilice el case, para que el usuario eligiera la opción de la operación a realizar.

Igualmente en la parte de:
opciones(N, A, B) ->
case N of
1 -> A+B;
2 -> A-B;
3 -> A*B;
4 -> A/B;
N when N > 4 -> "Ingresa otra opcion (1-4)"
end.
se encuentran el módulo llamado opc y la función que utilice a la cual llame opciones y le puse una aridad de 3.
En opciones(N, A, B), N es el número de opción que el usuario elegirá, A y B son los dos datos que el usuario introducirá, con los cuales se realizará la operación. Y ya en la parte donde se encuentra el case N of, pues sencillamente ya se presentan las opciones junto con su operación a realizar, es decir, si se ingresa el 1 como opción, entonces se realizará una suma, si se ingresa el 2, una resta, si se ingresa el 3, se realiza una multiplicación, si se ingresa un 4, se realiza una divisón. Y si se ingresa un número mayor a 4, entonces en la terminal se imprime que se ingrese otra opción de 1-4. La función case al final termina con end.

Para ejecutar este programa colocamos erl en la terminal y después:
c(opc). 
Aquí les muestro la imagen de la ejecución de este programa, en donde elijo las diferentes opciones y la opción de cuando N > 4.


Y el otro programa que realice lo llame areas.erl. Y es el siguiente:

Código
-module(areas).
-export([cuadrado/1]).
-export([triangulo/2]).
-export([rombo/2]).
-export([trapecio/3]).
-export([circulo/1]).
-export([rectangulo/2]).

cuadrado(L) ->
L*L.

triangulo(B, H) ->
(B*H) / 2.

rombo(DM, D) ->
(DM*D) / 2.

trapecio(BM, B, H) ->
((BM+B)*H) / 2.

circulo(R) ->
3.141592*(R*R).

rectangulo(B, A) ->
B*A.
Pues este programa también es muy sencillo, calculas las áreas de ciertas figuras geométricas.
Como vemos coloque el módulo con su nombre, areas, y además exporte cada una de las funciones por separado, las cuales se pueden exportar juntas, de la siguiente manera:
-export([cuadrado/1, triangulo/2, rombo/2, trapecio/3, circulo/1, rectangulo/2]).
A cada función le di una cierta aridad, según los datos que se necesitan para calcular las diferentes areas.
Y ya después coloque a cada función con su instrucción correspondiente.
Como vemos las areas que calcula son: la del cuadrado, la del triángulo, la del rombo, la del trapecio, la del círculo y la del rectángulo. Las cuales se calculan mediante las fórmulas:

Área del cuadrado = Lado * Lado
Área del triángulo = Base * Altura / 2
Área del rombo = Diámetro mayor * Diámetro menor / 2
Área de l trapecio = ((Base mayor + Base menor ) * Altura) / 2
Área del círculo = 3.141592 * radio al cuadrado
Área del rectángulo = Base por Altura

Al final de cada instrucción se colocará un punto .

Para ejecutar este programa, escribiremos erl en la terminal y después lo siguiente:
c(areas).
Y aquí les muestro la imagen de la ejecución de este programa, donde utilice todas las funciones.


Saludos.





sábado, 13 de noviembre de 2010

Lenguaje Funcional Erlang

Erlang es un lenguaje funcional y concurrente que fue desarrollado por Ericcson para la aplicación de telecomunicaciones.
Aunque Ericcson era originalmente el propietario del lenguaje Erlang, en el año 1998 el lenguaje fue cedido como open source.

Erlang es un de los pocos lenguajes de programación declarativos que es exitoso en el mundo empresarial.
Además pertenece a los lenguajes orientados a mensajes, los cuales proporcionan concurrencia osuando procesos paralelos. La concurrencia, es que varios procesos se lleven a cabo (sean ejecutados) al mismo tiempo.

Hablando de Erlang como un lenguaje orientado a mensajes, la interacción que se da entre los threads (procesos) en dichos lenguajes, se lleva a cabo mediante el envío y la recepción de mensajes.

El equipo de Erlang desarrollo ciertas caracterisitcas en el lenguajes de acuerdo a los requisitos que tienen las aplicaciones de telecomunicaciones, las cuales son: alta disponibilidad, modificación del código sin detener la aplicación, y demás.

Bueno, tomando en cuenta estos requisitos, algunas de las caracteristicas desarrollados por el equipo de Erlang son:
  • Concurrencia
  • Lenguaje funcional
  • Tolerancia a fallos
  • Reemplazo de código en caliente
  • Comunicación entre los procesos mediante mensajes.
El soporte de concurrencia, se dice que es la mayor fortaleza de Erlang, y como ya lo mencione anteriormente, la concurrencia es cuando se llevan a cabo o se ejecutan varios procesos al mismo tiempo.

Además ,Erlang es un lenguaje funcional, ya que esta estructurado por definición de funciones.
Los programas en Erlang se componen de bloques funcionales, llamados funciones.
Podemos identificar una función en un programa en Erlang, mediante el nombre y la aridad de la función, dicha aridad es el número de datos de entrada, que se permitirán en la función. Es decir, la función volumen/3, permite solo 3 datos de entrada mientras que la función area/2, permite solo 2 datos de entrada.

Algo muy importante que hay que mencionar es que pueden coexisitir sin ningun problema dos funciones con el mismo nombre y diferente aridad, como por ejemplo: multiplicación/2 y multiplicación/3, ya que las dos funciones son diferentes.

La definición de una función es la siguiente:
nombre-función(Argumento1, Argumento2, ...)  ->
instruccion,
instruccion,
Resultado-a-devolver.
Las funciones se agrupan en módulos, los cuales son las unidades mínimas de compilación en Erlang. Cada módulo tiene un nombre, único en el programa y se almacena en un fichero fuente, y dicho fichero tiene el nombre del módulo.
Las primeras líneas del fichero contienen la definición del módulo y las funciones que se exportan; las funciones que no sean exportadas, no podrán ser utilizadas fuera de este mismo módulo.

En Erlang el módulo y su función o funciones se escriben de la manera siguiente:
-module(nombre_modulo).
-export([funcion1/2, funcion2/1, funcion3/4]).

También se pueden poner las funciones por separado, es decir, así:
-module(nombre_modulo).
-export([funcion1/2]).
-export([funcion2/1]).
-export([funcion3/4]).
Hay que poner atención en el . que hay al final del módulo y de las funciones exportadas.

En cuanto a la tolerancia a fallos, se puede mencionar que la idea en Erlang sobre estos errores o fallos que se pueden dar, es encontrar una buena forma de manejar dichos errores y problemas en lugar de prevenirlos.

En el reemplazo de código en caliente, puedo mencionar que la unidad mínima de reemplazo son los módulos.
Pueden estar cargadas en memoria al mismo tiempo dos versiones diferentes de un mismo módulo, pero cuando se realiza la llamada a una función, la versión que se utilizará será la última versión disponible del módulo.

Como lo mencione anteriormente la interacción o comunicación que hay entre los threads (procesos), se realiza mediante mensajes.

Bueno, a continuación les mostraré un sencillo ejemplo de un programa en Erlang, al que llame operaciones.
La extensión de los programas en Erlang es .erl
Además el nombre del módulo del programa deberá ser el mismo nombre del programa, en este caso el nombre del módulo es operaciones.

Código
-module(operaciones).
-export([suma/2]).
-export([resta/2]).
-export([multiplicacion/2]).
-export([division/2]).

suma(A,B) ->
A+B.

resta(C,D) ->
C-D.

multiplicacion(E,F) ->
E*F.

division(G,H) ->
G / H.
En sí, este programa realiza las operaciones básicas, como son la suma, la resta, la multiplicación y la división.

En la parte de:
-module(operaciones).
-export([suma/2]).
-export([resta/2]).
-export([multiplicacion/2]).
-export([division/2]).
estan introducidos el módulo y las diferentes funciones junto con su aridad, dichas funciones no pueden llevar acentos. Cada función tiene una aridad de 2, es decir cada función solo puede recibir 2 datos de entrada.
Al final de cada módulo y de cada función exportada deberá ir un punto .
Y en esta parte:
suma(A,B) ->
A+B.

resta(C,D) ->
C-D.

multiplicacion(E,F) ->
E*F.

division(G,H) ->
G / H.
se encuentra cada función con su instrucción.

Dentro de los () de cada función, van las variables, que serán los datos que el usuario introducirá, es decir, los datos de entrada. Estas variables solo pueden ir en mayúscula, y en todas las funciones se pueden poner las mismas variables, en este caso no lo hicé así.
Al final de cada instrucción, deberá ir también un punto .

Bueno para compilar este programa, iremos a la terminal y escribiremos erl (si ya lo tenemos instalado), y después teclearemos lo siguiente:
c(operaciones).
Es decir, se escribe c(nombre_del_programa)). (con punto al final).
Y si el programa esta totalmente bien, si ningún error, entonces nos aparecerá:
{ok,operaciones}
Y ahora si, ya podemos introducir datos, para que sean realizadas las distintas operaciones.
Por ejemplo, para una suma, se deberá introducir, lo siguiente:
operaciones:suma(A,B).
En donde A,B serán cualesquiera números.
Bueno, primero se pone el nombre del módulo (o nombre del programa, que es el mismo nombre del módulo), después :(dos puntos) y luego el nombre de la función (suma, resta, multiplicacion o division) y seguido dentro de paréntesis, se escriben los valores que queremos que sean sumados, restados, multiplicados o divididos.

En cuanto a la división también aparte del /, se puede escribir div, pero este solo funciona para enteros, es decir, si se quiere obtener la división de 3 entre 6, en vez de que el resultado sea 0.5, será 0, y al dividir 29 entre 2, en vez de que resulte 14.5, se obtiene 14. Así, que si se desean divisiones, en donde el resultado no será un entero, se recomienda utilizar el /.

Bueno, aquí les colocó la imagen de la ejecución de este programa, en donde realice cada una de las operaciones:

*Nota: Para salir de la ejecución del programa se escribe halt().

Bueno, aquí están las referencias en las que me base para realizar esta entrada.

Programación en Erlang
Erlang(1)
Erlang (Concurrencia)
Erlang(2)

Aquí les dejo el código.
operaciones.erl

Saludos.

miércoles, 10 de noviembre de 2010

Cálculo Lambda

El cálculo lambda fue desarrollado por Alonso Church en el año de 1930. En sí fue desarrollado para dar una definición precisa de lo que es una función.
Además el cálculo lambda también puede ser usado para definir en una forma precisa lo que es una función computable. Se dice que este ćalculo es universal ya que puede expresar y evaluar cualequier funcion computable. Por esta razón el cálculo lambda es equivalente a las máquinas de Turing, sin embargo el cálculo λ es una propuesta más cercana al software que al hardware.

El cálculo lambda trabaja con objetos llamados lambda-términos, los cuales son cadenas de símbolos como una de las siguientes forma:
  • v
  • λv.E1
  • (E1 E2)
Donde v es una variable, y donde E1 y E2 son lambda-términos. Y los términos de la forma λv.E1 son abstracciones, de lo cual, les hablaré más adelante.

El cálculo lambda se puede considerar como el lenguaje universal más pequeño. Ha sido empleado también como fundamento conceptual de los lenguajes de programación.

Sintaxis
La sintaxis del Cálculo Lambda es:
<término>::= <variable> |
λ<variable>.<término> |
(<término><término>)

Esta sintaxis solo representa a las funciones con un argumento.
Si se quieren mas argumentos sería de la siguiente forma:
λx1.λ x2. .... λxn. M

Un término o expresión en el cálculo lambda se define recursivamente mediante las reglas siguientes:
  • Todas las variables son términos, es decir cada una de las variables es un término.
  • Suponiendo que x es una variable y t es un término, entonces (λx.t) es un término llamado abstracción lambda.
  • Suponiendo que t y s son términos, entonces (ts) es un término llamado aplicación lambda.
  • Ninguna otra cosa más que lo anterior, es un término.
Una abstracción lambda o abstracción funcional λx.t representa una función que toma solo a un argumento, además se dice que λ liga la variable x en el término t.


Por otra parte, la aplicación lambda o aplicación funcional ts representa la aplicación de un argumento s a una función t.
La aplicación lambda tiene el formato (M N) y dicha aplicación tendrá un resultado.
Para calcular el resultado de una aplicación lambda o funcional será atraves de la generación de expresiones equivalentes por la aplicación de las reglas del cálculo λ.

La relación de equivalencia entre las expresiones del cálculo λ tendrá las siguientes propiedades:
  • Reflexividad M = M
  • Simetría M = N -> N = M
  • Transitividad M = N Λ N = P -> M = P
También tendrá las siguientes reglas:
M = N -> (M P) = (N P)
M = N -> (P M) = (P N)
M = N -> λx.N = λx.M

Ocurrencia de los términos
Dado en el siguiente término, se ejemplifica la ocurrencia:
((xy)λx.(xy))

(xy) ocurre dos veces
x ocurre tres veces
y ocurre dos veces

Ahora definiré lo que es ocurrencia ligada.
Una ocurrencia de la variable x en un término P es ligada, solamente si x ocurre en un subtérmino de P de la forma λx.M; esto se puede aplicar en el siguiente término: (λy.(yy)λx.(xy)

En sí,
x y y ocurren ligadas en el término anterior, ya que este término contiene a los subtérminos:

λy.(yy) -> donde y ocurre ligada tres veces
λx.(xy) -> donde x ocurre ligada dos veces.

Ahora definiré lo que es ocurrencia libre.
Si x ocurre libre en un término de P por lo menos una vez, entonces x es una variable libre de P.
Esto es:
Bueno, en si esto es lo que trata el Cálculo Lambda.
Aquí les dejaré las referencias que utilice para este tema:

Paradigmas de Programación: Cálculo Lambda.
Cálculo Lambda.
Cálculo
λ


Saludos.

domingo, 7 de noviembre de 2010

Máquinas de Turing

La máquina de Turing es un modelo computacional autómata que de una forma secuencial realiza una lectura/escritura de datos, moviéndose en los dos sentidos, derecha e izquierda.

Kurt Gödel descubrió que ciertos teoremas matemáticos aunque eran ciertos no podían ser probados por personas, entonces aquí entra lo que es el concepto de máquina de Turing, introducido por Alan Mathison Turing, quien quería demostrar que estos teoremas se podían probar de una manera mecánica a través de la máquina de Turing.


La máquina de Turing esta conformada por:

  • Una cinta. Una cinta es infinita y esta conformada por celdas o casillas, además sobre ella se realiza la lectura/escritura de los datos. Las celdas en las que en un principio no se ha escrito nada, contienen un carácter especial nulo o vacío que se representa por medio de un 0 o por medio de #. En cada celda se puede escribir un símbolo de un conjunto finito de símbolos llamado alfabeto de la máquina.
  • Un cabezal. Hay un dispositivo que se mueve sobre la cinta, el cual contiene un cabezal. El cabezal se puede mover a la derecha y a la izquierda de la posición en que se encuentre de la cinta. Además el cabezal puede leer el contenido de una celda, de una en una, o escribir en la celda cualquier símbolo de su alfabeto .
  • Un registro de estado. El registro de estado es el que almacena los estados de la máquina. Lo estados de la máquina son finitos y la máquina no tiene que empezar exactamente con un estado especifico.
  • Tabla de acción. Contiene las instrucciones que se realizarán, y al ejecutarse estas instrucciones, se siguen los siguientes pasos:
  1. Se lee el carácter o símbolo en la posición que se encuentra el cabezal.
  2. Se escribe un nuevo símbolo en esa posición (puede ser el mismo que había). El símbolo que se escriba tiene que ser del alfabeto de la máquina y además depende del estado actual y del carácter leído.
  3. Se desplaza el cabezal una celda ya sea a la izquierda o a la derecha.
  4. Se decidirá cual será el nuevo estado en función del estado actual y del carácter que se acaba de leer. Si la tabla de acción no tiene ya correspondencia con el estado actual y con el símbolo, entonces la máquina ya no realiza su funcionamiento, es decir la máquina detiene su funcionamiento.
Ejemplo de una suma de dos números.
Para realizar la suma de dos números, representaremos a cada número tantos unos como se el tamaño del número, es decir, que si vamos a sumar los números 3 y 5, entonces al número 3 lo representaremos así, 111 (3 veces 1) y al número 5 lo representaremos así 11111 (5 veces 1).

Si tenemos a los dos números que sumaremos, separados por un 0, entonces lo que haríamos para sumarlos, sería cambiar un 1 de cualquier extremo de la cinta a un 0, y después al 0 que esta separando a los dos números lo convertiríamos a un 1. Así, ya tendríamos todos los unos juntos, es decir, ya tendríamos los dos números (3 y 5) juntos, es decir, ya estarían sumados.

Es decir, esto sería así:
Cinta
0000111011111000

Ahora colocaremos un 0 en el primer 1 de la izquierda.
0000011011111000

Ahora, colocaremos un 1 en donde se encuentra el 0 de separación.
0000011111111000

Y ahora que ya tenemos todos los unos juntos, es decir los dos números, 3 y 5, ya tenemos la suma, que es 8 unos, entonces la suma de 3 y 5 es 8.

Veamos esto ahora implementándolo con la máquina de Turing.

Vamos a suponer que la máquina se encuentra del lado izquierdo. Empezamos con el estado A y como el cabezal no se encuentra necesariamente antes del primer número, en este caso en el 111 (3), haremos que el cabezal llegue hasta allí sin alterar los caracteres anteriores a este número. Lo que haremos, será que cuando el cabezal lea un 0 en una celda y este en estado A, entonces se escribirá un cero, es decir no se alterará nada, después se volverá al estado A y se moverá hacia la derecha.

Después al moverse a la derecha se llegará al primer número, es decir al 111 (3), y como nos encontraremos en estado A y llegamos a un 1, entonces se cambiará al 1 por un 0 (este 1 es el único que debemos cambiar a 0 como lo mencione anteriormente, cambiar un 1 de cualquier extremo de la cinta a un 0). Como seguiremos a la derecha para llegar al 0 de separación, nos encontraremos con mas unos, entonces como nos encontramos en estado A, esos unos se convertirían en ceros, pero no queremos esto, ya que queremos juntar los unos, para realizar la suma de los dos números, entonces lo que haremos será añadir un nuevo estado B, que cuando se encuentre un 1 en estado A, se deberá pasar a estado B.

Ya cuando se convirtió en 0 el 1, el estado A se pasa a estado B, entonces se seguirá desplazando el cabezal hacia la derecha hasta llegar al 0 de separación, sin alterar nada y cuando se va desplazando el cabezal por cada celda y se encuentra un 1 en estado B, entonces este 1 se convertirá en un 1 y se pasará el cabezal hacia la derecha y se pasará de nuevo a estado B. Y ya cuando llegue a una celda en donde encuentre el carácter 0, significa que ha llegado al 0 de separación y si esta en estado B, entonces este 0 se convertirá a 1.

Ahora que la suma esta terminada, entonces la máquina deberá de parar y pasar a un estado correspondiente, al cual llamaremos @. Cuando la máquina llega a este estado, ya no leerá ninguna celda mas y tampoco ya no se desplazará, entonces la máquina se detendrá.

El programa de este ejemplo con la máquina Turing es así (donde > es desplazarse hacia la derecha):

           0         1 

A 0,A,> 0,B,>

B 1,@ 1,B,>

Las páginas en las que me base son las siguientes:

Computación: Máquina de Turing
Máquina de Turing
Máquinas de Turing

Videos sobre la máquina de Turing