Rangos, arreglos y variables

Si tecleo algo:


In [1]:
3


Out[1]:
3

Me devuelve el valor de la expresión.

Si tecleo 2 cosas:


In [2]:
3
4


Out[2]:
4

Me devuelve la última únicamente.


In [3]:
3
4;

; implica que no devuelva nada (o al menos, que no lo imprima).


In [5]:
1:6


Out[5]:
1:6

In [6]:
typeof(ans)  # dame el tipo de la última respuesta


Out[6]:
UnitRange{Int64} (constructor with 1 method)

El objeto 1:6 es de tipo UnitRange, "rellenado" con enteros con 64 bits.

No es un arreglo. Para hacer un arreglo:


In [9]:
[1:6]


Out[9]:
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

Darle un nombre:


In [12]:
a = [1:6]


Out[12]:
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

In [13]:
a


Out[13]:
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

Un solo = quiere decir asignarle un valor a la variable del lado izquierdo.

Un rango ocupa (mucho) menos memoria que un arreglo y es más rápido. No almacena nada, sino va generando valores en el vuelo.

Cosas aleatorias


In [14]:
rand


Out[14]:
rand (generic function with 33 methods)

Si sólo pongo el nombre de una función, me dice que es una función.

Para llamarla, uso paréntesis:


In [15]:
rand()


Out[15]:
0.04356307688870609

Regresa un número ((p)seudo-)aleatorio uniformemente entre $0$ y $1$.


In [16]:
rand()


Out[16]:
0.789999205620963

En Julia, para averiguar cuál función se está llamando, usamos @which y ponemos la llamada completa de la función:


In [17]:
@which rand()


Out[17]:
rand() at random.jl:90

In [18]:
rand(1:6)


Out[18]:
6

[Si uso Ctrl-Enter, se queda en la misma celda.]


In [30]:
6 * rand()


Out[30]:
3.3084213096475072

Quiero enteros:


In [55]:
int(6 * rand())


Out[55]:
2

In [56]:
int(3.6)


Out[56]:
4

¡int redondea!


In [58]:
floor(3.6)


Out[58]:
3.0

In [59]:
floor(-3.6)


Out[59]:
-4.0

In [60]:
floor(6 * rand())


Out[60]:
1.0

In [80]:
ceil(6 * rand())


Out[80]:
3.0

In [81]:
1 + floor(6 * rand())


Out[81]:
4.0

In [85]:
function dado()
    int( 1 + floor(6 * rand()) )
end


Out[85]:
dado (generic function with 1 method)

In [86]:
function dado2()
    rand(1:6)
end


Out[86]:
dado2 (generic function with 1 method)

In [88]:
function dado(num_caras)
    int( 1 + floor(num_caras * rand()) )
end


Out[88]:
dado (generic function with 2 methods)

In [89]:
dado


Out[89]:
dado (generic function with 2 methods)

In [102]:
dado()


Out[102]:
4

In [137]:
dado(2) # una moneda


Out[137]:
1

In [138]:
dado


Out[138]:
dado (generic function with 2 methods)

In [139]:
methods(dado)


Out[139]:
2 methods for generic function dado:
  • dado() at In[85]:2
  • dado(num_caras) at In[88]:2

In [140]:
function dado(num_caras=6)
    int( 1 + floor(num_caras * rand()) )
end


Out[140]:
dado (generic function with 2 methods)

In [141]:
methods(dado)


Out[141]:
2 methods for generic function dado:
  • dado() at In[140]:2
  • dado(num_caras) at In[140]:2

In [142]:
dado()


Out[142]:
5

In [143]:
dado(10)


Out[143]:
9

El valor por default (num_caras=6) hace dos métodos distintos de la función.


In [144]:
methods(rand)


Out[144]:
33 methods for generic function rand:

In [145]:
rand(1:6, 10)


Out[145]:
10-element Array{Int64,1}:
 2
 2
 1
 3
 2
 5
 3
 5
 1
 3

In [146]:
@which rand(1:6, 10)


Out[146]:
rand(r::Range{T},dims::Int64...) at random.jl:230

In [148]:
@which rand(6, 10)


Out[148]:
rand(dims::Int64...) at random.jl:123

In [149]:
rand(6,10)


Out[149]:
6x10 Array{Float64,2}:
 0.708952  0.742682  0.559812  0.156959   …  0.767235   0.903509   0.219137
 0.226769  0.604338  0.935293  0.804932      0.0915998  0.0187165  0.402203
 0.90555   0.665427  0.956179  0.32574       0.656727   0.0332827  0.712346
 0.517341  0.52146   0.982712  0.888286      0.176674   0.9213     0.381029
 0.567297  0.996252  0.29146   0.0787309     0.431528   0.494437   0.721535
 0.858869  0.634158  0.538799  0.700424   …  0.815579   0.329559   0.21473 

In [151]:
rand(1:6, 3,4)


Out[151]:
3x4 Array{Int64,2}:
 1  1  4  6
 3  5  6  2
 1  4  5  4

In [152]:
@which rand(1:6, 3,4)


Out[152]:
rand(r::Range{T},dims::Int64...) at random.jl:230

In [154]:
rand(1:2, 2, 2, 2)


Out[154]:
2x2x2 Array{Int64,3}:
[:, :, 1] =
 1  2
 1  2

[:, :, 2] =
 1  1
 2  1

In [155]:
rand(1:2, 2, 2, 2, 2)


Out[155]:
2x2x2x2 Array{Int64,4}:
[:, :, 1, 1] =
 1  2
 1  2

[:, :, 2, 1] =
 2  2
 2  2

[:, :, 1, 2] =
 2  1
 1  2

[:, :, 2, 2] =
 2  1
 2  2

Esto se llama multiple dispatch (despacho múltiple)


In [156]:
function dados(N)
    rand(1:6, N)
end


Out[156]:
dados (generic function with 1 method)

In [157]:
dados(N) = rand(1:6, N)


Out[157]:
dados (generic function with 1 method)

In [167]:
N = 10
tiros = dados(N)


Out[167]:
10-element Array{Int64,1}:
 5
 4
 5
 3
 1
 1
 3
 2
 1
 6

In [168]:
cara1 = 0

for i in 1:length(tiros)
    if tiros[i] == 1
        cara1 = cara1 + 1
    end
end

In [169]:
cara1


Out[169]:
3

In [174]:
cara1     = 0
   for i in 1:length(tiros)
if  tiros[i] == 1     cara1 = cara1 + 1 end
end

In [171]:
cara1


Out[171]:
3

In [ ]:
c = 0

for i in 1:length(t)
    if t[i] == 1
        c = c + 1
    end
end

Unas versiones más:


In [175]:
caras = zeros(6)


Out[175]:
6-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

In [177]:
caras = zeros(Int, 6)


Out[177]:
6-element Array{Int64,1}:
 0
 0
 0
 0
 0
 0

In [178]:
@which zeros(Int, 6)


Out[178]:
zeros(T::Type{T<:Top},dims...) at array.jl:169

In [179]:
#caras = [0, 0, 0, 0, 0, 0]
caras = zeros(Int, 6)

for i in 1:length(tiros)
    if tiros[i] == 1
        caras[1] = caras[1] + 1
    end
    if tiros[i] == 2
        caras[2] = caras[2] + 1
    end
end

In [180]:
caras


Out[180]:
6-element Array{Int64,1}:
 3
 0
 0
 0
 0
 0

In [182]:
caras[1]  # el valor de la primera entrada de caras


Out[182]:
3

In [183]:
hola = 10


Out[183]:
10

In [187]:
hola[2]


BoundsError()
while loading In[187], in expression starting on line 1

 in getindex at number.jl:15

In [190]:



Out[190]:
true

Teorema: Si te encuentras haciendo algo más de 2 veces, ¡hay que automatizarlo!


In [194]:
a = 3
b = 3.0


Out[194]:
3.0

In [195]:
a == b


Out[195]:
true

In [196]:
a === b


Out[196]:
false

In [199]:
c = int32(10)
d = int64(10)
c == d, c === d, is(c, d)


Out[199]:
(true,false,false)

In [200]:
===


Out[200]:
is

In [201]:
is


Out[201]:
is

In [202]:
typeof(ans)


Out[202]:
Function

In [203]:
is(is, is)


Out[203]:
true

In [204]:
is === is


Out[204]:
true

Automatizar:


In [207]:
caras = zeros(Int, 6)

for i in 1:length(tiros)
    for valor in 1:6
        if tiros[i] == valor
            caras[valor] += 1
        end
    end
    
end

[El editor de IJulia es CodeMirror]


In [208]:
caras


Out[208]:
6-element Array{Int64,1}:
 3
 1
 2
 1
 2
 1

Construimos un histograma (en la interpretación estadística de la palabra. Ejercicio: Checa si realmente se llame histograma).

Normalizar: dividir entre el número de tiradas:


In [211]:
sum(caras)


Out[211]:
10

In [213]:
?sum


INFO: Loading help data...
Base.sum(itr)

   Returns the sum of all elements in a collection.

Base.sum(A, dims)

   Sum elements of an array over the given dimensions.

Base.sum(f, itr)

   Sum the results of calling function "f" on each element of
   "itr".

In [212]:
methods(sum)


Out[212]:
13 methods for generic function sum:

In [210]:
caras / suma(caras)


suma not defined
while loading In[210], in expression starting on line 1

sum actúa sobre iterables, por ejemplo rangos:


In [214]:
sum(1:6)


Out[214]:
21

In [215]:
sum(1:.1:6)


Out[215]:
178.5

In [216]:
1:.1:6


Out[216]:
1.0:0.1:6.0

In [217]:
typeof(ans)


Out[217]:
FloatRange{Float64} (constructor with 1 method)

In [218]:
[1:.1:6]


Out[218]:
51-element Array{Float64,1}:
 1.0
 1.1
 1.2
 1.3
 1.4
 1.5
 1.6
 1.7
 1.8
 1.9
 2.0
 2.1
 2.2
 ⋮  
 4.9
 5.0
 5.1
 5.2
 5.3
 5.4
 5.5
 5.6
 5.7
 5.8
 5.9
 6.0

In [219]:
probabilidades = caras / sum(caras)


Out[219]:
6-element Array{Float64,1}:
 0.3
 0.1
 0.2
 0.1
 0.2
 0.1

In [220]:
sum(probabilidades)


Out[220]:
1.0000000000000002

In [221]:
big(0.2)


Out[221]:
2.00000000000000011102230246251565404236316680908203125e-01 with 256 bits of precision

In [222]:
widen(0.2)


Out[222]:
2.00000000000000011102230246251565404236316680908203125e-01 with 256 bits of precision

In [224]:
BigFloat("0.2")


Out[224]:
2.000000000000000000000000000000000000000000000000000000000000000000000000000004e-01 with 256 bits of precision

In [225]:
big(10)


Out[225]:
10

In [226]:
BigFloat(0.2)


Out[226]:
2.00000000000000011102230246251565404236316680908203125e-01 with 256 bits of precision

Graficar

Necesitamos importar un paquete de gráficos. Usaremos PyPlot (wrapper de matplotlib)


In [227]:
using PyPlot

In [ ]:


In [240]:
figure(figsize=(5,3))
plot(probabilidades, "ro-")
ylim(0, 0.4)
xlim(-1, 6)
xlabel("cara")
ylabel("probabilidad")


Out[240]:
PyObject <matplotlib.text.Text object at 0x11e22d590>

In [241]:
plt.hist(tiros)


Out[241]:
([3.0,0.0,1.0,0.0,2.0,0.0,1.0,0.0,2.0,1.0],[1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0],{PyObject <matplotlib.patches.Rectangle object at 0x11e3ef650>,PyObject <matplotlib.patches.Rectangle object at 0x11e3efc90>,PyObject <matplotlib.patches.Rectangle object at 0x11e3fd350>,PyObject <matplotlib.patches.Rectangle object at 0x11e3fd9d0>,PyObject <matplotlib.patches.Rectangle object at 0x11e3fded0>,PyObject <matplotlib.patches.Rectangle object at 0x11e409710>,PyObject <matplotlib.patches.Rectangle object at 0x11e409d90>,PyObject <matplotlib.patches.Rectangle object at 0x11e418450>,PyObject <matplotlib.patches.Rectangle object at 0x11e418ad0>,PyObject <matplotlib.patches.Rectangle object at 0x11e418fd0>})

Mi gráfica está más bonita que el histograma horrible de PyPlot -- c.f. Edward Tufte

Encapsular todo en una función


In [248]:
N = 100
tiros = rand(1:6, N);

In [250]:
function histograma(datos, num_cajas)
    
    @show datos
    
    conteos = zeros(Int, num_cajas)

    for i in 1:length(datos)
        for caja in 1:num_cajas
            if datos[i] == caja
                conteos[caja] += 1
            end
        end

    end
    
    @show conteos
    
    probabilidades = conteos / length(datos)
    
end

probabilidades = histograma(tiros, 6)

plot(probabilidades)


datos => [6,1,5,4,6,1,3,5,2,3,6,5,6,6,3,1,2,6,6,2,6,6,6,3,4,4,4,3,2,2,5,5,2,6,1,4,3,2,6,5,2,6,2,6,6,1,3,3,3,6,2,1,3,6,4,5,1,6,5,6,5,3,4,6,6,5,3,1,3,4,1,6,4,1,3,1,4,4,3,5,2,2,2,3,2,2,3,1,1,4,1,1,3,5,5,2,6,4,3,4]
conteos => [15,16,19,14,13,23]
Out[250]:
1-element Array{Any,1}:
 PyObject <matplotlib.lines.Line2D object at 0x11e4d15d0>

In [251]:
function plot_probas(probabilidades)

    figure(figsize=(5,3))
    plot(probabilidades, "ro-")
    ylim(0, 0.4)
    xlim(-1, 6)
    xlabel("cara")
    ylabel("probabilidad")
end


Out[251]:
plot_probas (generic function with 1 method)

In [252]:
plot_probas(probabilidades)


Out[252]:
PyObject <matplotlib.text.Text object at 0x11e51f810>

In [253]:
pwd()


Out[253]:
"/Users/dsanders/Dropbox/docencia/metodos-monte-carlo/2015-2/clases"

In [254]:
;ls


02-10 Sintaxis de Julia y dados.ipynb
histograma.jl

In [255]:
include("histograma.jl")


Out[255]:
histograma (generic function with 1 method)

In [ ]: