Números de Fibonacci

Los números de Fibonacci se definen así:

$$F_0=0, F_1=1$$$$F_{n} = F_{n-1} + F_{n-2}$$

y tenemos $F_2=1,F_3=2,F_4=3,F_5=5,F_6=8\dots$

También se puede definir el vector $$\mathbf{v}_n=\left( \begin{array}{c} F_{n}\\F_{n-1} \end{array} \right)$$ con dos números de Fibonacci consecutivos, y entonces tenemos las ecuaciones $$ \left( \begin{array}{c} F_{n}\\F_{n-1} \end{array} \right)= \left(\begin{array}{cc} 1 & 1\\ 1 & 0 \end{array}\right) \cdot \left( \begin{array}{c} F_{n-1}\\F_{n-2} \end{array} \right) $$

Iterando, podemos calcular el número de Fibonacci $F_{n}$ como $$ \left( \begin{array}{c} F_{n}\\F_{n-1} \end{array} \right)= \left(\begin{array}{cc} 1 & 1\\ 1 & 0 \end{array}\right)^{n-1} \cdot \left( \begin{array}{c} F_{1}\\F_0 \end{array} \right)= \left(\begin{array}{cc} 1 & 1\\ 1 & 0 \end{array}\right)^{n-1} \cdot \left( \begin{array}{c} 1\\0 \end{array} \right) $$

Vamos a comparar varias técnicas para calcular las potencias de la matriz $$ M = \left(\begin{array}{cc} 1 & 1\\ 1 & 0 \end{array}\right) $$

  1. Multiplicando n veces la matriz $M$.
  2. Multiplicando la matriz $M$, pero usando que para calcular por ejemplo $M^8$ no necesitamos 8 multiplicaciones, sino solo 3: $M^8=(M^4)\cdot (M^4)$, $M^4=(M^2)\cdot (M^2)$, $M^2=M\cdot M$.
  3. Usando la diagonalización de $M$.

Usaremos en ambos casos funciones que reciben dos argumentos:

  • Una matriz $A$
  • Un exponente $n$ y devuelven la matriz $A^n$
In [3]:
M = [1,1; 1,0]
F10 = [1; 0]
M =

   1   1
   1   0

F10 =

   1
   0

In [7]:
#Método 1
# ATENCION: para usar este código desde matlab
# es necesario compiar este código en un archivo de nombre
# potencia1.m y que ese archivo este en el PATH
function P = potencia1(A,n)
%Calcula la potencia A^n de una matriz A a un exponente n
%
%Utiliza una iteración sencilla, multiplicando la identidad por A n veces
%
%Para calcular A^n tiene que hacer n productos de matrices 2x2.
%Cada producto de matrices 2x2 necesita 8 multiplicaciones luego el
%número de multiplicaciones necesarias es 8*n
    [d,d] = size(A);
    P = eye(d);
    for i = [1:n]
        P = A*P;
    end
end
In [10]:
for i = [1:10]
    sprintf('M a la potencia %d',i)
    potencia1(M,i)
end
ans = M a la potencia 1
ans =

   1   1
   1   0

ans = M a la potencia 2
ans =

   2   1
   1   1

ans = M a la potencia 3
ans =

   3   2
   2   1

ans = M a la potencia 4
ans =

   5   3
   3   2

ans = M a la potencia 5
ans =

   8   5
   5   3

ans = M a la potencia 6
ans =

   13    8
    8    5

ans = M a la potencia 7
ans =

   21   13
   13    8

ans = M a la potencia 8
ans =

   34   21
   21   13

ans = M a la potencia 9
ans =

   55   34
   34   21

ans = M a la potencia 10
ans =

   89   55
   55   34

In [9]:
%Los numeros de Fibonacci F_n y F_{n-1}
n = 6
potencia1(M,n-1)*F10
n =  6
ans =

   8
   5

Ejercicio

  • Explica con palabras cómo funciona este método de multiplicación.
  • ¿Crees que puede tener ventajas sobre el método anterior?
In [11]:
%Método 2
% ATENCION: para usar este código desde matlab
% es necesario compiar este código en un archivo de nombre
% potencia2.m y que ese archivo este en el PATH
function P = potencia2(A,n)
%Calcula la potencia A^n de una matriz A a un exponente n
%
%TAREA: Explica cómo funciona ...
    if n==0
        [d,d] = size(A);
        P = eye(d);
    else
        resto = mod(n, 2);
        cociente = floor(n/2);
        An2 = potencia2(A, cociente);
        if resto==0
            P = An2 * An2;
        else
            P = An2 * An2 * A;
        end
    end
end
In [13]:
for i = [1:10]
    sprintf('M a la potencia %d',i)
    potencia2(M,i)
end
ans = M a la potencia 1
ans =

   1   1
   1   0

ans = M a la potencia 2
ans =

   2   1
   1   1

ans = M a la potencia 3
ans =

   3   2
   2   1

ans = M a la potencia 4
ans =

   5   3
   3   2

ans = M a la potencia 5
ans =

   8   5
   5   3

ans = M a la potencia 6
ans =

   13    8
    8    5

ans = M a la potencia 7
ans =

   21   13
   13    8

ans = M a la potencia 8
ans =

   34   21
   21   13

ans = M a la potencia 9
ans =

   55   34
   34   21

ans = M a la potencia 10
ans =

   89   55
   55   34

In [14]:
%Los numeros de Fibonacci F_n y F_{n-1}
n = 6
potencia2(M,n-1)*F10
n =  6
ans =

   8
   5

In [ ]:

Ejercicio

Usa ahora la diagonalización de M. Debajo tienes los comandos necesarios

In [15]:
%Método 3
%TAREA: escribe el cuerpo de la funcion

function P = potencia3(A,n)
%Calcula la potencia A^n de una matriz A a un exponente n
%
%    Utiliza la diagonalización A = P*D*Pinv
%    y la formula A^n = P*(D^n)*Pinv
end
In [18]:
B = [0,1; 4,0]

[avecs, avals] = eig(B);
P = avecs
D = avals
Pinv = inv(P)
B =

   0   1
   4   0

P =

   0.44721  -0.44721
   0.89443   0.89443

D =

Diagonal Matrix

   2.0000        0
        0  -2.0000

Pinv =

   1.11803   0.55902
  -1.11803   0.55902

In [19]:
%Recuperamos la matriz B mediante P*D*Pinv (con error numérico)
P*D*Pinv
ans =

   1.3385e-15   1.0000e+00
   4.0000e+00  -2.0819e-16

In [20]:
%Comparamos B@B@B con P*(D*D*D)*Pinv
B*B*B
ans =

    0    4
   16    0

In [21]:
% de nuevo error numérico
P*(D*D*D)*Pinv
ans =

   8.6201e-15   4.0000e+00
   1.6000e+01   1.9890e-15

In [22]:
% Para obtener potencias de matrices diagonales podemos usar esta función
function Dn = potencia_diagonal(D,n)
%Devuelve D^n, para D una matriz diagonal y n un número entero
%    
%Si D no es diagonal, o n no es entero, devuelve un resultado incorrecto
    %Cuando el argumento de diag es una matriz, devuelve los elementos de la diagonal
    valores_diagonal = diag(D);
    d = length(D);
    Dn = zeros(d);
    for i = [1:d]
        Dn(i,i) = valores_diagonal(i)^n;
    end
end
In [23]:
potencia_diagonal(D,3)
ans =

   8.00000   0.00000
   0.00000  -8.00000

In [ ]:

Movimiento de personas en el crucero

Amanece en nuestro crucero con las 1000 personas del pasaje en los camarotes, en el nivel 2. Cada hora, su ubicación puede haber cambiado:

  • Cada persona tiene una probabilidad del 20% de quedarse en el camarote, del 40% de moverse de su a la cubierta superior y del 40% de moverse al nivel 1.
  • Una persona en el nivel 1 tiene una probabilidad del 50% de quedarse en el nivel 1, del 30% de moverse a cubierta y del 20% de moverse al nivel 2.
  • Una persona en la cubierta superior tiene una probabilidad del 40% de quedarse en cubierta, del 30% de moverse al nivel 1 y del 30% de moverse al nivel 2.

Definimos la cantidad de personas $x_n$ en cubierta, $y_n$ en el nivel 1 y $z_n$ en el nivel 2, transcurridas $n$ horas.

Planteamos las ecuaciones de cantidad de personas en cada nivel como un sistema matricial $$\left(\begin{array}{c} x_{n + 1}\\ y_{n + 1}\\ z_{n + 1} \end{array}\right) = \left(\begin{array}{ccc} 0.4 & 0.3 & 0.4\\ 0.3 & 0.5 & 0.4\\ 0.3 & 0.2 & 0.2 \end{array}\right) \cdot \left(\begin{array}{c} x_n\\ y_n\\ z_n \end{array}\right)$$ Este modelo puede predecir una cantidad de personas en cubierta que no es un entero. No es un problema, porque debe interpretarse como un número medio.

Al igual que antes podemos expresar la cantidad de gente en la hora n directamente en función de la cantidad de gente en la hora inicial $n=0$.

$$\left(\begin{array}{c} x_{n }\\ y_{n}\\ z_{n} \end{array}\right) = \left(\begin{array}{ccc} 0.4 & 0.3 & 0.4\\ 0.3 & 0.5 & 0.4\\ 0.3 & 0.2 & 0.2 \end{array}\right)^n \cdot \left(\begin{array}{c} x_0\\ y_0\\ z_0 \end{array}\right) = \left(\begin{array}{ccc} 0.4 & 0.3 & 0.4\\ 0.3 & 0.5 & 0.4\\ 0.3 & 0.2 & 0.2 \end{array}\right)^n \cdot \left(\begin{array}{c} 0\\ 0\\ 1000 \end{array}\right) $$

Usando potencias de matrices, calcula la cantidad esperada de gente en cubierta al cabo de 1,2,3 y 4 horas.

In [24]:
M = [0.4, 0.3, 0.4; 0.3, 0.5, 0.4; 0.3, 0.2, 0.2]
M =

   0.40000   0.30000   0.40000
   0.30000   0.50000   0.40000
   0.30000   0.20000   0.20000

In [ ]:

In [ ]:

In [ ]:

$$M = \left(\begin{array}{ccc} 0.4 & 0.3 & 0.4\\ 0.3 & 0.5 & 0.4\\ 0.3 & 0.2 & 0.2 \end{array}\right)$$
  • Calcula potencias de la matriz $M$ con exponentes hasta 10, y luego para exponentes 100 y 1000: ¿qué observas?
  • Explica el comportamiento de la matriz usando la fórmula, observando los autovalores de la matriz $M$: $$ M^n = P\cdot D^n\cdot P^{-1} = P\cdot \left(\begin{array}{ccc} d_1^n & 0 & 0\\ 0 & d_2^n & 0\\ 0 & 0 & d_3^n \end{array}\right) \cdot P^{-1} $$
In [ ]:

In [ ]:

Una matriz con entradas positivas, tal que la suma de las entradas de cada columna es 1, se denomina "matriz estocástica". Las matrices estocásticas aparecen yosal modelizar procesos estocásticos en los que un sistema puede moverse de uno a otro estado (una persona cambia de cubierta, un barco puede estar en espera, cargando, descargado, repostando o en ruta, etc).

Es un resultado conocido que una matriz estocástica tiene el autovalor 1, y el resto de autovalores, sean reales o complejos, tienen módulo menor que 1.

  • Si tenemos una matriz estocástica $M$ cuyos autovalores tienen todos multiplicidad 1 (que es en cierto sentido "lo más habitual"), describe el límite: $\lim_{n\rightarrow \infty}M^n$.
In [ ]:

In [ ]:

Exponencial de una matriz

Podemos definir la exponencial de un número $x$ mediante la serie:

$$e^x = \exp(x) = \sum_{n=0}^\infty \frac{1}{n!}x^n$$

y podemos definir la exponencial de una matriz $x$ mediante la serie:

$$e^M =\exp(M) = \sum_{n=0}^\infty \frac{1}{n!}M^n$$

Como vistéis en clase, es más práctico diagonalizar la matriz para calcular:

$$e^M = \sum_{n=0}^\infty \frac{1}{n!}P\cdot D^n \cdot P^{-1} = P\cdot \left(\begin{array}{ccc} \sum_{n=0}^\infty \frac{(d_1)^n}{n!} & \dots & 0\\ \vdots & \dots & \vdots\\ \vdots & \dots & \sum_{i=0}^\infty \frac{(d_3)^n}{n!} \end{array}\right) \cdot P^{-1} = P\cdot \left(\begin{array}{ccc} \exp(d_1) & \dots & 0\\ \vdots & \dots & \vdots\\ \vdots & \dots & \exp(d_3) \end{array}\right) \cdot P^{-1} $$

Ejercicio

  • Para las matrices de abajo, aproxima la exponencial de la matriz sumando términos de la serie y usando la diagonalización de la matriz, y compara los resultados obtenidos. Debes escribir funciones que reciben como argumento una matriz $M$ y devuelven la exponencial $\exp(M)$, pero que la calculan de formas diferentes...
In [73]:
function eM = exponencial1(M, truncar=10)
%Recibe como argumento una matriz M y devuelve la exponencial de M
%
%Suma varios términos de la serie (1/n!)*M^n, terminando en el valor "truncar"
%que se pasó como argumento. Calcula las potencias M^n sin diagonalizar M.
    # TAREA: completa la función
end
In [74]:
function eM = exponencial2(M, truncar=10)
%Recibe como argumento una matriz M y devuelve la exponencial de M
%
%Utiliza la diagonalización A = P*D*Pinv
%y la formula exp(A) = P*exp(D)*Pinv
    # TAREA: completa la función
end
In [75]:
M1 = [1,1; 1,0]
M1 =

   1   1
   1   0

In [76]:
M2= [0.4, 0.3, 0.4; 0.3, 0.5, 0.4; 0.3, 0.2, 0.2]
M2 =

   0.40000   0.30000   0.40000
   0.30000   0.50000   0.40000
   0.30000   0.20000   0.20000

In [ ]:

In [ ]:

Coseno

Busca el desarrollo en serie del coseno, y repite el ejercicio anterior para el cálculo del coseno de una matriz.

In [ ]:

In [ ]:

In [ ]:

In [ ]:

In [ ]: