s1Eva_IT2012_T2_MN Modelo Leontief

Ejercicio: 1Eva_IT2012_T2_MN Modelo Leontief

Planteamiento

X – TX = D

A(I-T) = D

(I-T)X = D

para el algoritmo:

A = I – T

B = D


Algoritmo en Python

Resultados del algoritmo

respuesta X: 
[[158.56573701]
 [288.73225044]
 [323.87373581]]
verificar A.X=B: 
[[ 79.99999997]
 [139.99999998]
 [200.        ]]
>>> itera
8
>>>

Instrucciones en Python

# Método de Gauss-Seidel
# solución de sistemas de ecuaciones
# por métodos iterativos

import numpy as np

# INGRESO
T = np.array([[0.40, 0.03, 0.02],
              [0.06, 0.37, 0.10],
              [0.12, 0.15, 0.19]])
A = np.identity(3) - T

B = np.array([80.0, 140.0, 200.0],dtype=float)

X0 = np.array([200.0,200.0,200.0])

tolera = 0.00001
iteramax = 100

# PROCEDIMIENTO
# Gauss-Seidel
tamano = np.shape(A)
n = tamano[0]
m = tamano[1]
#  valores iniciales
X = np.copy(X0)
diferencia = np.ones(n, dtype=float)
errado = 2*tolera

itera = 0
while not(errado<=tolera or itera>iteramax):
    # por fila
    for i in range(0,n,1):
        # por columna
        suma = 0 
        for j in range(0,m,1):
            # excepto diagonal de A
            if (i!=j): 
                suma = suma-A[i,j]*X[j]
        
        nuevo = (B[i]+suma)/A[i,i]
        diferencia[i] = np.abs(nuevo-X[i])
        
        X[i] = nuevo
    errado = np.max(diferencia)
    itera = itera + 1

# Respuesta X en columna
X = np.transpose([X])

# revisa si NO converge
if (itera>iteramax):
    X=0
# revisa respuesta
verifica = np.dot(A,X)

# SALIDA
print('respuesta X: ')
print(X)
print('verificar A.X=B: ')
print(verifica)

s1Eva_IIT2011_T2 Sistema de Ecuaciones, diagonal dominante

Ejercicio: 1Eva_IIT2011_T2 Sistema de Ecuaciones, diagonal dominante

1. Desarrollo analítico

Solución iterativa usando el método de Jacobi

El sistema de ecuaciones

\begin{cases} -2x+5y+9z=1\\7x+y+z=6\\-3x+7y-z=-26\end{cases}

cambia a su forma matricial AX=B

\begin{bmatrix} -2 & 5 & 9 \\ 7 & 1 & 1 \\ -3 & 7 &-1 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} 1 \\ 6 \\ -26 \end{bmatrix}

y luego como matriz aumentada y realizar el pivoteo parcial por filas, buscando hacerla diagonal dominante:

\begin{pmatrix} 7 & 1 & 1 &6\\ -3 & 7 &-1 & -26\\ -2 & 5 & 9 &1 \end{pmatrix}

las ecuaciones para el algoritmo se obtienen despejando una variable diferente en cada ecuación.

x_{i+1}=\frac{6-y_i-z_i}{7} y_{i+1}=\frac{-26+3x_i+z_i}{7} z_{i+1}=\frac{1+2x_i-5y_i}{9}

Dado el vector inicial X0= [0, 0, 0], y una tolerancia de 0.0001, e desarrollan al menos 3 iteraciones:

El error se verifica para éste ejercicio como el mayor valor de la diferencia entre iteraciones consecutivas. Analogía al video del acople entre las aeronaves. Si una coordenada aún no es la correcta …. menor a lo tolerado, pues NO hay acople…

itera = 0

x_1=\frac{6-(0)-(0)}{7} = 0.8571 y_1=\frac{-26+3(0)+(0)}{7} = -3,7142 z_1=\frac{1+2(0)-5(0)}{9} =0.111 diferencia = [ 0.8571 -0 , -3,7142 -0 ,0.1111- 0 ] = [ 0.8571 , -3,7142,0.1111 ] errado = max |diferencia| = 3,7142

error es más alto que lo tolerado

X_1= [ 0.8571 , -3.7142 ,0.1111 ]

Itera = 1

x_2=\frac{6-(-3,7142) -0.1111}{7} = 1.3718 y_2=\frac{-26+3(0.8571)+0.1111}{7} = -3.3310 z_2=\frac{1+2(0.8571)-5(-3,7142)}{9} = 2.3650 diferencia = [ 1.3718-0.8571 , -3.3310 -(-3.7142) , 2.3650 - 0.1111 ] = [0.5146 , 0.3832, 2.2539 ] errado = max |diferencia| = 2.2539

el error disminuye, pero es más alto que lo tolerado

X_2= [ 1.3718 , -3.3310, 2.3650 ]

Itera = 2

x_3 = \frac{6-(-3.3310)-2.3650}{7} = 0.9951 y_3 = \frac{-26+3(1.3718)+2.3650}{7} = -2.7884 z_3 = \frac{1+2(1.3718)-5(-3.3310)}{9} = 2.2665 diferencia = [ 0.9951 - 1.3718 , -2.7884 -(-3.3310) , 2.2665- 2.3650] diferencia = [ -0.3766 , 0.5425 , -0.0985] errado = max |diferencia| = 0.5425

el error disminuye, pero es más alto que lo tolerado

X_3= [ 0.9951 , -2.7884 , 2.2665]

Observación: Si el error disminuye en cada iteración, se puede intuir que se converge a la solución. Se puede continuar con la 4ta iteración…


2. Solución numérica usando Python

Usando el algoritmo desarrollado en clase se obtiene la respuesta con 13 iteraciones:

Matriz aumentada
[[ -2.   5.   9.   1.]
 [  7.   1.   1.   6.]
 [ -3.   7.  -1. -26.]]
Pivoteo parcial:
  1 intercambiar filas:  0 y 1
  2 intercambiar filas:  1 y 2
AB
Iteraciones Jacobi
itera,[X],errado
0 [0. 0. 0.] 1.0
1 [ 0.85714286 -3.71428571  0.11111111] 3.7142857142857144
2 [ 1.37188209 -3.33106576  2.36507937] 2.2539682539682544
3 [ 0.99514091 -2.78846777  2.26656589] 0.5425979915775843
4 [ 0.93170027 -2.96400162  1.8814023 ] 0.3851635892452223
5 [ 1.0117999  -3.04621384  1.96482318] 0.0834208883015708
6 [ 1.01162724 -2.99996816  2.02829656] 0.06347337312830126
7 [ 0.99595309 -2.99097453  2.00256614] 0.025730417621558477
8 [ 0.99834406 -3.0013678   1.99408654] 0.010393267289710018
9 [ 1.00104018 -3.00155447  2.0003919 ] 0.006305364149447268
10 [ 1.00016608 -2.99949822  2.00109475] 0.002056248145824391
11 [ 0.99977193 -2.99977243  1.99975814] 0.0013366043333828959
12 [ 1.00000204 -3.0001323   1.99982289] 0.0003598675094789172
13 [ 1.0000442  -3.00002443  2.00007395] 0.0002510632800638568
14 [ 0.99999292 -2.99997049  2.00002339] 5.3934767063168465e-05
respuesta de A.X=B : 
[ 0.99999292 -2.99997049  2.00002339]
iterado, incluyendo X0:  15

La gráfica muestra las coordenadas de las aproximaciones, observe el espiral que se va cerrando desde el punto inicial en verde al punto final en rojo.

Se debe controlar el número de iteraciones para verificar la convergencia con iteramax.

NO es necesario almacenar los valores de los puntos, solo el último valor y el contador itera permite determinar si el sistema converge.

# 1Eva_IIT2011_T2 Sistema de Ecuaciones, diagonal dominante
# MATG1052 Métodos Numéricos
# propuesta: edelros@espol.edu.ec,
import numpy as np

def jacobi(A,B,X0, tolera, iteramax=100, vertabla=False):
    ''' Método de Jacobi, tolerancia, vector inicial X0
        para mostrar iteraciones: vertabla=True
    '''
    A = np.array(A,dtype=float)
    B = np.array(B,dtype=float)
    X0 = np.array(X0,dtype=float)
    tamano = np.shape(A)
    n = tamano[0]
    m = tamano[1]
    diferencia = np.ones(n, dtype=float)
    errado = np.max(diferencia)
    X = np.copy(X0)
    xnuevo = np.copy(X0)
    tabla = [np.copy(X0)]

    itera = 0
    if vertabla==True:
        print('Iteraciones Jacobi')
        print('itera,[X],errado')
        print(itera, xnuevo, errado)
    while not(errado<=tolera or itera>iteramax):
        
        for i in range(0,n,1):
            nuevo = B[i]
            for j in range(0,m,1):
                if (i!=j): # excepto diagonal de A
                    nuevo = nuevo-A[i,j]*X[j]
            nuevo = nuevo/A[i,i]
            xnuevo[i] = nuevo
        diferencia = np.abs(xnuevo-X)
        errado = np.max(diferencia)
        X = np.copy(xnuevo)
        
        tabla = np.concatenate((tabla,[X]),axis = 0)

        itera = itera + 1
        if vertabla==True:
            print(itera, xnuevo, errado)

    # No converge
    if (itera>iteramax):
        X=itera
        print('iteramax superado, No converge')
    return(X,tabla)

def pivoteafila(A,B,vertabla=False):
    '''
    Pivotea parcial por filas, entrega matriz aumentada AB
    Si hay ceros en diagonal es matriz singular,
    Tarea: Revisar si diagonal tiene ceros
    '''
    A = np.array(A,dtype=float)
    B = np.array(B,dtype=float)
    # Matriz aumentada
    nB = len(np.shape(B))
    if nB == 1:
        B = np.transpose([B])
    AB  = np.concatenate((A,B),axis=1)
    
    if vertabla==True:
        print('Matriz aumentada')
        print(AB)
        print('Pivoteo parcial:')
    
    # Pivoteo por filas AB
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    
    # Para cada fila en AB
    pivoteado = 0
    for i in range(0,n-1,1):
        # columna desde diagonal i en adelante
        columna = np.abs(AB[i:,i])
        dondemax = np.argmax(columna)
        
        # dondemax no es en diagonal
        if (dondemax != 0):
            # intercambia filas
            temporal = np.copy(AB[i,:])
            AB[i,:] = AB[dondemax+i,:]
            AB[dondemax+i,:] = temporal

            pivoteado = pivoteado + 1
            if vertabla==True:
                print(' ',pivoteado, 'intercambiar filas: ',i,'y', dondemax+i)
    if vertabla==True:
        if pivoteado==0:
            print('  Pivoteo por filas NO requerido')
        else:
            print('AB')
    return(AB)

# PROGRAMA Búsqueda de solucion
# INGRESO --------

# INGRESO
A = [[-2, 5, 9],
     [ 7, 1, 1],
     [-3, 7,-1]]

B = [1, 6,-26]

X0 = [0, 0,  0]
tolera = 0.0001
iteramax = 100

# PROCEDIMIENTO --------
AB = pivoteafila(A,B,vertabla=True)
# separa matriz aumentada en A y B
[n,m] = np.shape(AB)
A = AB[:,:m-1]
B = AB[:,m-1]

[X, puntos] = jacobi(A,B,X0,tolera,vertabla=True)
iterado = len(puntos)
# SALIDA --------
print('respuesta de A.X=B : ')
print(X)
print('iterado, incluyendo X0: ', iterado)

# GRAFICA DE ITERACIONES
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

figura = plt.figure() # Una hoja para dibujar
grafica = figura.add_subplot(111,projection = '3d')

# Puntos de la iteración
pxi = puntos[:,0]
pyi = puntos[:,1]
pzi = puntos[:,2]
grafica.plot(pxi,pyi,pzi, color = 'magenta',
             label = 'puntos[i]')
grafica.scatter(pxi[0],pyi[0],pzi[0], color = 'green', marker='o')
grafica.scatter(pxi[iterado-1],pyi[iterado-1],pzi[iterado-1],
                color = 'red', marker='o')

grafica.set_title('Puntos de iteración')
grafica.set_xlabel('eje x')
grafica.set_ylabel('eje y')
grafica.set_zlabel('eje z')
grafica.legend()
plt.show()

Gráfica de planos

Dado que el sistema de ecuaciones es de tres incógnitas, la solución se puede interpretar como la intersección de los planos formados por cada una de las ecuaciones en el espacio X,Y,Z.

Sistema Ecuaciones Diagonal Dominante 02

se comenta la última instrucción del algoritmo anterior, #plt.show(), y se añaden las siguientes líneas al algoritmo anterior para obtener la gráfica:

# Tema 2. Sistema de ecuaciones 3x3
# Concepto como interseccion de Planos
##import matplotlib.pyplot as plt
##from mpl_toolkits.mplot3d import Axes3D

ax = -5     # Intervalo X
bx = 5
ay = ax-2   # Intervalo Y
by = bx+2

muestras = 11

# PROCEDIMIENTO --------
# Ecuaciones de planos
z0 = lambda x,y: (-A[0,0]*x - A[0,1]*y + B[0])/A[0,2]
z1 = lambda x,y: (-A[1,0]*x - A[1,1]*y + B[1])/A[1,2]
z2 = lambda x,y: (-A[2,0]*x - A[2,1]*y + B[2])/A[2,2]

xi = np.linspace(ax,bx, muestras)
yi = np.linspace(ay,by, muestras)
Xi, Yi = np.meshgrid(xi,yi)

Z0 = z0(Xi,Yi)
Z1 = z1(Xi,Yi)
Z2 = z2(Xi,Yi)

# solución al sistema
punto = np.linalg.solve(A,B)

# SALIDA
print('respuesta de A.X=B : ')
print(punto)

# Interseccion entre ecuación 1 y 2
# PlanoXZ, extremo inferior de y
Aa  = np.copy(A[0:2,[0,2]])
Ba  = np.copy(B[0:2])
Ba  = Ba-ay*A[0:2,1]
pta = np.linalg.solve(Aa,Ba)
pa  = np.array([ay])
pxza = np.array([pta[0],ay,pta[1]])

# PlanoXZ, extremo superior de y
Bb  = np.copy(B[0:2])
Bb  = Bb-by*A[0:2,1]
ptb = np.linalg.solve(Aa,Bb)
pb  = np.array([by])
pxzb = np.array([ptb[0],by,ptb[1]])

# GRAFICA de planos
fig3D = plt.figure()
graf3D = fig3D.add_subplot(111, projection='3d')

graf3D.plot_wireframe(Xi,Yi,Z0,
                       color ='blue',
                       label='Z1')
graf3D.plot_wireframe(Xi,Yi,Z1,
                       color ='green',
                       label='Z2')
graf3D.plot_wireframe(Xi,Yi,Z2,
                       color ='orange',
                       label='Z3')
# recta intersección planos 1 y 2
graf3D.plot([pxza[0],pxzb[0]],
            [pxza[1],pxzb[1]],
            [pxza[2],pxzb[2]],
            label='Sol 1y2',
            color = 'violet',
            linewidth = 4)
# Punto solución del sistema 3x3
graf3D.scatter(punto[0],punto[1],punto[2],
                color = 'red',
                marker='o',
                label ='punto',
                linewidth = 6)

graf3D.set_title('Sistema de ecuaciones 3x3')
graf3D.set_xlabel('x')
graf3D.set_ylabel('y')
graf3D.set_zlabel('z')
graf3D.set_xlim(ax, bx)
graf3D.set_xlim(ay, by)
graf3D.legend()
graf3D.view_init(45, 45)
# rotacion de ejes
for angulo in range(45, 360+45, 5 ):
    graf3D.view_init(45, angulo)
    plt.draw()
    plt.pause(.001)
plt.show()


Tarea: Realice las modificaciones necesarias para usar el algoritmo de Gauss-Seidel. Luego compare resultados.


Revisión de resultados

Si se usan las ecuaciones sin pivorear y cambiar a diagonal dominante, como fueron presentadas en el enunciado, el algoritmo Jacobi NO converge, el error aumenta, y muy rápido como para observar la espiral hacia afuera en una gráfica.

Xi, errado
[ -0.5   6.   26. ] 26.0
[ 131.5  -16.5   69.5] 132.0
[ 271. -984. -484.] 967.5
[-4638.5 -1407.  -7675. ] 7191.0
[-38055.5  40150.5   4092.5] 41557.5
[ 118792.  262302.  395246.] 391153.5
[ 2434361.5 -1226784.   1479764. ] 2315569.5
[  3591977.5 -18520288.5 -15890546.5] 17370310.5
....

s1Eva_IT2011_T3_MN Precios unitarios en factura, k

Ejercicio: 1Eva_IT2011_T3_MN Precios unitarios en factura, k

Las ecuaciones basadas en las sumas de cantidad.preciounitario representan el valor pagado en cada factura.

Siendo Xi el precio unitario de cada material:

2x_1 + 5x_2 + 4x_3 = 35 3x_1 + 9x_2 + 8x_3 = k 5x_1 + 3x_2 + x_3 = 17

se escriben en la forma matricial Ax=B

\begin{bmatrix} 2 && 5 && 4 \\ 3 && 9 && 8 \\ 5 && 3 && 1 \end{bmatrix}.\begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix}=\begin{bmatrix} 35 \\ k \\ 17 \end{bmatrix}

luego se escribe la matriz aumentada:

\begin{bmatrix} 2 && 5 && 4 && 35\\ 3 && 9 && 8 && k\\ 5 && 3 && 1 && 17\end{bmatrix}

se pivotea por filas buscando tener una matriz diagonal dominante,

\begin{bmatrix} 5 && 3 && 1 && 17 \\ 3 && 9 && 8 && k\\ 2 && 5 && 4 && 35\\\end{bmatrix}

Luego se usa el procedimiento de eliminación hacia adelante,

\begin{bmatrix} 5 && 3 && 1 && 17 \\ 3-5\frac{3}{5} && 9-3\frac{3}{5} && 8-1\frac{3}{5} && k-17\frac{3}{5} \\ 2-5\frac{2}{5} && 5-3\frac{2}{5} && 4-1\frac{2}{5} && 35-17\frac{2}{5} \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && \frac{36}{5} && \frac{37}{5} && k-\frac{51}{5} \\ 0 && \frac{19}{5} && \frac{18}{5} && \frac{141}{5} \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 19 && 18 && 141 \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 19-36\frac{19}{36} && 18-37\frac{19}{36} && 141-(5k-51)\frac{19}{36} \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 0 && \frac{-55}{36} && \frac{6045-5k}{36} \end{bmatrix}

multiplicando la última fila por 36,

\begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 0 && -55 && 6045-5k \end{bmatrix}

con lo que se pueden obtener cada precio unitario en función de k.
Como variante, se continua siguiendo el procedimieno de Gauss, dejando como tarea el uso de Gauss-Jordan

-55x_3 = 6045-5k x_3 = -\frac{6045-5k}{55} 36 x_2 + 37 x_3 = 5k-51 x_2 = \frac{1}{36}(5k-51 - 37 x_3) x_2 = \frac{1}{36} \Big( 5k-51 - 37 \big(-\frac{6045-5k}{55}\big) \Big) 5x_1 + 3 x_2 +x_3 = 17 x_1 = \frac{1}{5} \Big[ 17 - 3 x_2 - x_3 \Big] x_1 = \frac{1}{5} \Big[17-3\frac{1}{36} \Big( 5k-21 - 37 \big(-\frac{6045-5k}{55}\big) \Big) - \Big( -\frac{6045-5k}{55} \Big) \Big]

para luego simplificar las expresiones (tarea).

En el literal c se indica que el valor de k es 65, con lo que se requiere sustituir en la solución el valor de K para encontrar los precios unitarios.

\begin{bmatrix} 5 && 3 && 1 && 17 \\ 3 && 9 && 8 && 65\\ 2 && 5 && 4 && 35\\\end{bmatrix}

Se encuentra que:

el vector solución X es:

[[-0.18181818]
 [ 5.18181818]
 [ 2.36363636]]

Lo que muestra que debe existir un error en el planteamiento del enunciado, considerando que los precios NO deberían ser negativos como sucede con el primer precio unitario de la respuesta.

que es lo que suponemos ser trata de corregir en el literal d, al indicar que se cambie en la matriz el valor de 5 por 5.1. Los resultados en éste caso son más coherentes con el enunciado. Todas las soluciones son positivas.

A = np.array([[ 5.1, 3  , 1],
              [ 3. , 9  , 8],
              [ 2. , 5.1, 4]])
B1 = np.array([ 17, 65, 35])

el vector solución X es:
[[0.33596838]
 [3.88669302]
 [3.62648221]]

El error relativo de los precios encontrados entre las ecuaciones planteadas es:

diferencia = [0.335968-0.181818,
              3.886693-5.181818, 
              3.626482-2.363636]
           = [0.154150, -1.295125, 1.262845]
error(dolares) = max|diferencia| = 1.295125
Por las magnitudes de los precios, el error se aprecia
usando el error relativo referenciado 
al mayor valor de la nueva solución
error relativo = 1.295125/3.886693 = 0.333220
es decir de aproximadamente 33%

Para revisar otra causa del error se analiza el número de condición de la matriz:

>>> A
array([[5.1, 3. , 1. ],
       [3. , 9. , 8. ],
       [2. , 5.1, 4. ]])
>>> np.linalg.cond(A)
60.28297696795716

El número de condición resulta lejano a 1, por lo que para éste problema:
pequeños cambios en la matriz de entrada producen grandes cambios en los resultados.

por ejemplo: un 0.1/5= 0.02 que es un 2% de variación en la entrada produce un cambio del 33% en el resultado.

Algoritmo en Python

Resultados del algoritmo

Matriz aumentada
[[ 2.  5.  4. 35.]
 [ 3.  9.  8. 65.]
 [ 5.  3.  1. 17.]]
Pivoteo parcial:
  1 intercambiar filas:  0 y 2
[[ 5.  3.  1. 17.]
 [ 3.  9.  8. 65.]
 [ 2.  5.  4. 35.]]
Elimina hacia adelante:
 fila 0 pivote:  5.0
   factor:  0.6  para fila:  1
   factor:  0.4  para fila:  2
 fila 1 pivote:  7.2
   factor:  0.5277777777777778  para fila:  2
 fila 2 pivote:  -0.3055555555555558
[[ 5.00000000e+00  3.00000000e+00  1.00000000e+00  1.70000000e+01]
 [ 0.00000000e+00  7.20000000e+00  7.40000000e+00  5.48000000e+01]
 [ 0.00000000e+00 -4.44089210e-16 -3.05555556e-01 -7.22222222e-01]]
Elimina hacia Atras:
 fila 2 pivote:  -0.3055555555555558
   factor:  -24.2181818181818  para fila:  1
   factor:  -3.2727272727272703  para fila:  0
 fila 1 pivote:  7.1999999999999895
   factor:  0.4166666666666671  para fila:  0
 fila 0 pivote:  5.0
[[ 1.00000000e+00  0.00000000e+00  0.00000000e+00 -1.81818182e-01]
 [ 0.00000000e+00  1.00000000e+00  0.00000000e+00  5.18181818e+00]
 [-0.00000000e+00  1.45338287e-15  1.00000000e+00  2.36363636e+00]]
solución X: 
[-0.18181818  5.18181818  2.36363636]
>>>

Instrucciones en Python

# 1Eva_IT2011_T3_MN Precios unitarios en factura, k
# Método de Gauss-Jordan
# Solución a Sistemas de Ecuaciones
# de la forma A.X=B

import numpy as np

def pivoteafila(A,B,vertabla=False):
    '''
    Pivotea parcial por filas
    Si hay ceros en diagonal es matriz singular,
    Tarea: Revisar si diagonal tiene ceros
    '''
    A = np.array(A,dtype=float)
    B = np.array(B,dtype=float)
    # Matriz aumentada
    nB = len(np.shape(B))
    if nB == 1:
        B = np.transpose([B])
    AB  = np.concatenate((A,B),axis=1)
    
    if vertabla==True:
        print('Matriz aumentada')
        print(AB)
        print('Pivoteo parcial:')
    
    # Pivoteo por filas AB
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    
    # Para cada fila en AB
    pivoteado = 0
    for i in range(0,n-1,1):
        # columna desde diagonal i en adelante
        columna = np.abs(AB[i:,i])
        dondemax = np.argmax(columna)
        
        # dondemax no es en diagonal
        if (dondemax != 0):
            # intercambia filas
            temporal = np.copy(AB[i,:])
            AB[i,:] = AB[dondemax+i,:]
            AB[dondemax+i,:] = temporal

            pivoteado = pivoteado + 1
            if vertabla==True:
                print(' ',pivoteado, 'intercambiar filas: ',i,'y', dondemax+i)
    if vertabla==True:
        if pivoteado==0:
            print('  Pivoteo por filas NO requerido')
        else:
            print(AB)
    return(AB)

def gauss_eliminaAdelante(AB, vertabla=False,lu=False,casicero = 1e-15):
    ''' Gauss elimina hacia adelante, a partir de,
    matriz aumentada y pivoteada.
    Para respuesta en forma A=L.U usar lu=True entrega[AB,L,U]
    '''
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    L = np.identity(n,dtype=float) # Inicializa L
    if vertabla==True:
        print('Elimina hacia adelante:')
    for i in range(0,n,1):
        pivote = AB[i,i]
        adelante = i+1
        if vertabla==True:
            print(' fila',i,'pivote: ', pivote)
        for k in range(adelante,n,1):
            if (np.abs(pivote)>=casicero):
                factor = AB[k,i]/pivote
                AB[k,:] = AB[k,:] - factor*AB[i,:]

                L[k,i] = factor # llena L
                
                if vertabla==True:
                    print('   factor: ',factor,' para fila: ',k)
            else:
                print('  pivote:', pivote,'en fila:',i,
                      'genera division para cero')
    respuesta = AB
    if vertabla==True:
        print(AB)
    if lu==True:
        U = AB[:,:n-1]
        respuesta = [AB,L,U]
    return(respuesta)

def gauss_eliminaAtras(AB, vertabla=False, precision=5, casicero = 1e-15):
    ''' Gauss-Jordan elimina hacia atras
    Requiere la matriz triangular inferior
    Tarea: Verificar que sea triangular inferior
    '''
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    
    ultfila = n-1
    ultcolumna = m-1
    if vertabla==True:
        print('Elimina hacia Atras:')
        
    for i in range(ultfila,0-1,-1):
        pivote = AB[i,i]
        atras = i-1  # arriba de la fila i
        if vertabla==True:
            print(' fila',i,'pivote: ', pivote)
            
        for k in range(atras,0-1,-1):
            if (np.abs(AB[k,i])>=casicero):
                factor = AB[k,i]/pivote
                AB[k,:] = AB[k,:] - factor*AB[i,:]
                
                if vertabla==True:
                    print('   factor: ',factor,' para fila: ',k)
            else:
                print('  pivote:', pivote,'en fila:',i,
                      'genera division para cero')
 
        AB[i,:] = AB[i,:]/AB[i,i] # diagonal a unos
    X = np.copy(AB[:,ultcolumna])
    
    if vertabla==True:
        print(AB)
    return(X)

# PROGRAMA ------------------------
# INGRESO
A = np.array([[2,5,4],
              [3,9,8],
              [5,3,1]])

B = np.array([[35],
              [65],
              [17]])

# PROCEDIMIENTO
AB = pivoteafila(A,B,vertabla=True)

AB = gauss_eliminaAdelante(AB,vertabla=True)

X = gauss_eliminaAtras(AB,vertabla=True)

# SALIDA
print('solución X: ')
print(X)

 

s1Eva_IT2011_T1_MN Fondo de inversión

Ejercicio: 1Eva_IT2011_T1_MN Fondo de inversión

Planteamiento

Siendo C(t), considerando A como un millón, A=1

C(t)=Ate^{-t/3}

Se observa la gráfica de la función que muestra el valor máximo en el intervalo entre [2, 5] , alrededor de  3

Para encontrar el valor del máximo, se requiere usar la derivada respecto al tiempo y encontrar el cruce por cero.

\frac{dC}{dt} = -t e^{-t/3} +e^{-t/3}

Adicionalmente, para el literal b en la gráfica se incluye como meta donde C(t) disminuye a 1/4 o 0.25. Lo que estaría en el intervalo entre [10, 14].

Instrucciones en Python para observar la función:

# 1ra Evaluación I Término 2011
# Tema 1. Fondo de Inversion
import numpy as np
import matplotlib.pyplot as plt

ft = lambda t: t*np.exp(-t/3)

a=0
b=20
tolera = 0.0001
muestras = 101
meta = 0.25
# PROCEDIMIENTO
# Observar la función entre [a,b]
ti = np.linspace(a,b,muestras)
fti = ft(ti)

# Salida
# Gráfica
plt.plot(ti,fti, label='f(t)')
plt.axhline(meta, color = 'r')
plt.axhline(0, color = 'k')
plt.legend()
plt.show()

literal a

Para encontrar el máximo se puede determinar la derivada con Sympy.

Para la derivada se usa la forma simbólica de la función, que se convierte a forma numérica lambda para evaluarla de forma más fácil y obtener la gráfica.

# Literal a) usando derivada simbólica
import sympy as sp
x = sp.Symbol('x')
fxs = x*sp.exp(-x/3)
dfxs = fxs.diff(x,1)

# convierte la expresión a lambda
dfxn = sp.utilities.lambdify(x,dfxs,'numpy')
dfxni = dfxn(ti)
print('derivada de la función: ')
print(dfxs)
# Gráfica de la derivada.
plt.plot(ti,dfxni, label='df(t)/dt')
plt.axhline(0, color = 'k')
plt.legend()
plt.show()

derivada de la función: 
-x*exp(-x/3)/3 + exp(-x/3)

Se busca la raíz con algún método, por ejemplo bisección, siendo f(x) = 0

f(t) = \frac{dC}{dt} = -t e^{-t/3} +e^{-t/3}

Desarrollo analítico

itera = 0, a = 2, b= 5

c = \frac{a+b}{2} =\frac{2+5}{2}=3.5 f(2) = -2 e^{-2/3} +e^{-2/3} =0.1711 f(3.5) = -5 e^{-3.5/3} +e^{-3.5/3} = -0.0519 f(5) = -5 e^{-5/3} +e^{-5/3} = -0.1259

cambio de signo del lado izquierdo

a = 2, b = 3.5

error = | 3.5-2 | = 1.5

itera = 1, a = 2, b = 3.5

c = \frac{2+3.5}{2}=2.75 f(2.75) = -2.75 e^{-2.75/3} +e^{-2.75/3} = 0.0333

cambio de signo del lado derecho

a = 2.75, b = 3.5

error = | 3.5-2.75 | = 0.75

itera = 2, a = 2.75, b = 3.5

c = \frac{2.75+3.5}{2}=3.125 f(3.125) = -3.125 e^{-3.125/3} +e^{-3.125/3} = -0.0147

cambio de signo del lado izquierdo

a = 2.75, b = 3.1255

error = | 3.12555-2.75 | = 0.375

y se continúa hasta alcanzar la tolerancia dada para el ejercicio.

Usando el algoritmo se encuentra luego de 14 iteraciones:

método de Bisección
i ['a', 'c', 'b'] ['f(a)', 'f(c)', 'f(b)']
   tramo
0 [2.  3.5 5. ] [ 0.1711 -0.0519 -0.1259]
   1.5
1 [2.   2.75 3.5 ] [ 0.1711  0.0333 -0.0519]
   0.75
2 [2.75  3.125 3.5  ] [ 0.0333 -0.0147 -0.0519]
   0.375
3 [2.75   2.9375 3.125 ] [ 0.0333  0.0078 -0.0147]
   0.1875
4 [2.9375 3.0312 3.125 ] [ 0.0078 -0.0038 -0.0147]
   0.09375
5 [2.9375 2.9844 3.0312] [ 0.0078  0.0019 -0.0038]
   0.046875
6 [2.9844 3.0078 3.0312] [ 0.0019 -0.001  -0.0038]
   0.0234375
7 [2.9844 2.9961 3.0078] [ 0.0019  0.0005 -0.001 ]
   0.01171875
8 [2.9961 3.002  3.0078] [ 0.0005 -0.0002 -0.001 ]
   0.005859375
9 [2.9961 2.999  3.002 ] [ 0.0005  0.0001 -0.0002]
   0.0029296875
10 [2.999  3.0005 3.002 ] [ 1.1979e-04 -5.9866e-05 -2.3935e-04]
   0.00146484375
11 [2.999  2.9998 3.0005] [ 1.1979e-04  2.9941e-05 -5.9866e-05]
   0.000732421875
12 [2.9998 3.0001 3.0005] [ 2.9941e-05 -1.4968e-05 -5.9866e-05]
   0.0003662109375
13 [2.9998 2.9999 3.0001] [ 2.9941e-05  7.4847e-06 -1.4968e-05]
   0.00018310546875
14 [2.9999 3.     3.0001] [ 7.4847e-06 -3.7422e-06 -1.4968e-05]
   9.1552734375e-05
raíz en:  3.000030517578125

Instrucciones en Python

# 1Eva_IT2011_T1_MN Fondo de Inversión
# Algoritmo de Bisección
# [a,b] se escogen de la gráfica de la función
# error = tolera
import numpy as np

def biseccion(fx,a,b,tolera,iteramax = 20, vertabla=False, precision=4):
    '''
    Algoritmo de Bisección
    Los valores de [a,b] son seleccionados
    desde la gráfica de la función
    error = tolera
    '''
    fa = fx(a)
    fb = fx(b)
    tramo = np.abs(b-a)
    itera = 0
    cambia = np.sign(fa)*np.sign(fb)
    if cambia<0: # existe cambio de signo f(a) vs f(b)
        if vertabla==True:
            print('método de Bisección')
            print('i', ['a','c','b'],[ 'f(a)', 'f(c)','f(b)'])
            print('  ','tramo')
            np.set_printoptions(precision)
            
        while (tramo>=tolera and itera<=iteramax):
            c = (a+b)/2
            fc = fx(c)
            cambia = np.sign(fa)*np.sign(fc)
            if vertabla==True:
                print(itera,np.array([a,c,b]),np.array([fa,fc,fb]))
            if (cambia<0):
                b = c
                fb = fc
            else:
                a = c
                fa = fc
            tramo = np.abs(b-a)
            if vertabla==True:
                print('  ',tramo)
            itera = itera + 1
        respuesta = c
        # Valida respuesta
        if (itera>=iteramax):
            respuesta = np.nan

    else: 
        print(' No existe cambio de signo entre f(a) y f(b)')
        print(' f(a) =',fa,',  f(b) =',fb) 
        respuesta=np.nan
    return(respuesta)

# INGRESO
fx  = lambda t: -t*np.exp(-t/3)/3 + np.exp(-t/3)
a = 2
b = 5
tolera = 0.0001

# PROCEDIMIENTO
respuesta = biseccion(fx,a,b,tolera,vertabla=True)
# SALIDA
print('raíz en: ', respuesta)

Determine el monto de la inversión inicial A necesaria para que el máximo sea igual a un millón de dólares. Como el máximo se encuentra en t=3, se tiene que:

C(t)=Ate^{-t/3} 1=A(3)e^{-3/3} A=\frac{1}{(3)e^{-1}} = 0.906093

considerando que las unidades se encuentran en millones.


literal b

Para el literal b, se busca la raíz usando el método de Newton-Raphson como se indica en el enunciado.
En la función nueva se usa el valor de A encontrado, y la meta establecida.
Se obtiene la misa derivada del problema anterior multiplicada por A, por ser solo un factor que multiplica a la función original. El valor de meta es una constante, que se convierte en cero al derivar.

resultado con el algoritmo:

['xi', 'xnuevo', 'tramo']
[[1.0000e+01 1.0880e+01 8.7987e-01]
 [1.0880e+01 1.1056e+01 1.7580e-01]
 [1.1056e+01 1.1076e+01 2.0098e-02]
 [1.1076e+01 1.1078e+01 1.9337e-03]
 [1.1078e+01 1.1078e+01 1.8202e-04]]
raiz en:  11.077880437153812
con error de:  0.00018201925869298918
>>>

Instrucciones en Python

# 1Eva_IT2011_T1_MN Fondo de Inversión 
# Método de Newton-Raphson
# Ejemplo 1 (Burden ejemplo 1 p.51/pdf.61)

import numpy as np

# INGRESO
fx  = lambda t: 0.906093*t*np.exp(-t/3) - 0.25
dfx = lambda t: -t*np.exp(-t/3)/3 + np.exp(-t/3)

x0 = 10
tolera = 0.001

# PROCEDIMIENTO
tabla = []
tramo = abs(2*tolera)
xi = x0
while (tramo>=tolera):
    xnuevo = xi - fx(xi)/dfx(xi)
    tramo  = abs(xnuevo-xi)
    tabla.append([xi,xnuevo,tramo])
    xi = xnuevo

# convierte la lista a un arreglo.
tabla = np.array(tabla)
n = len(tabla)

# SALIDA
print(['xi', 'xnuevo', 'tramo'])
np.set_printoptions(precision = 4)
print(tabla)
print('raiz en: ', xi)
print('con error de: ',tramo)

el valor de t para la meta es: 11.0779035867

s1Eva_IT2011_T1 Encontrar α en integral

Ejercicio: 1Eva_IT2011_T1 Encontrar α en integral

Desarrollo Analítico

Se iguala la ecuación al valor buscado = 10, y se resuelve

\int_{\alpha}^{2\alpha} x e^{x}dx = 10

siendo: μ = x , δv = ex, δu = δx , v = ex

\int u dv = uv - \int v \delta u xe^x \Big|_{\alpha}^{2 \alpha} - \int_{\alpha}^{2\alpha} e^{x}dx - 10 = 0 2\alpha e^{2 \alpha} -\alpha e^{\alpha} - (e^{2\alpha} - e^{\alpha}) - 10 = 0 (2\alpha-1)e^{2 \alpha}+ (1-\alpha) e^{\alpha} - 10 = 0

la función a usar en el método es

f(\alpha) = (2\alpha-1)e^{2 \alpha}+ (1-\alpha)e^{\alpha} -10

Se obtiene la derivada para el método de Newton Raphson

f'(\alpha) = 2e^{2 \alpha} + 2(2\alpha-1)e^{2 \alpha} - e^{\alpha} + (1-\alpha) e^{\alpha} f'(\alpha) = (2 + 2(2\alpha-1))e^{2 \alpha} +(-1 + (1-\alpha)) e^{\alpha} f'(\alpha) = 4\alpha e^{2 \alpha} -\alpha e^{\alpha}

la fórmula para el método de Newton-Raphson

\alpha_{i+1} = \alpha_i - \frac{f(\alpha)}{f'(\alpha)}

se prueba con α0 = 1, se evita el valor de cero por la indeterminación que se da por f'(0) = 0

iteración 1:

f(1) = (2(1)-1)e^{2(1)}+ (1-(1))e^{(1)} -10 f'(1) = 4(1) e^{2 (1)} -(1) e^{(1)} \alpha_{1} = 1- \frac{f(1)}{f'(1)}

\alpha_{1} = 1.0973
error = 0.0973

iteración 2:
f(2) = (2(1.0973)-1)e^{2(1.0973)}+ (1-(1.0973))e^{(1.0973)} -10

f'(2) = 4(1.0973) e^{2 (1.0973)} -(1.0973) e^{(1.0973)} \alpha_{2} = 1.0973 - \frac{f(1.0973)}{f'(1.0973)}

\alpha_{2} = 1.0853
error = 0.011941

iteración 3:
f(3) = (2(1.0853)-1)e^{2(1.0853)}+ (1-(1.0853))e^{(1.0853)} -10

f'(3) = 4(1.0853) e^{2 (1.0853)} -(1.0853) e^{(1.0853)} \alpha_{3} = 1.0853- \frac{f(1.0853)}{f'(1.0853)}

\alpha_{3} = 1.0851
error = 0.00021951

[  xi,          xnuevo,      f(xi),      f'(xi),       tramo ]
[  1.           1.0973      -2.6109      26.8379       0.0973]
[  1.0973e+00   1.0853e+00   4.3118e-01   3.6110e+01   1.1941e-02]
[  1.0853e+00   1.0851e+00   7.6468e-03   3.4836e+01   2.1951e-04]
[  1.0851e+00   1.0851e+00   2.5287e-06   3.4813e+01   7.2637e-08]
raiz:  1.08512526549

se obtiene el valor de la raíz con 4 iteraciones, con error de aproximación de 7.2637e-08

Desarrollo con Python

s1Eva_IT2010_T2_MN Uso de televisores

Ejercicio: 1Eva_IT2010_T2_MN Uso de televisores

Para la función dada:

p(x) =\frac{1}{2.5} \Big(-10 \sin \Big(\frac{12x}{7} \Big) e^{-\frac{24x}{7}} + \frac{48x}{7}e^{-\frac{8x}{7}} + 0.8 \Big)

0≤x≤4

literal a

El enunciado indica encontrar el máximo y luego el mínimo, por lo que la curva bajo análisis es la derivada de la función dp(x)/dx.

Adicionalmente, para encontrar los puntos se requiere usar el método de Newton-Raphson que corresponden a las raíces de dp(x)/dx. La función bajo análisis ahora es la derivada y para el método se usa la derivada: d2p(x)/dx2.

Al usar el computador para las fórmulas, se usa la forma simbólica de la función p(x), para obtener dpx y d2px.

primera derivada: 
-3.13469387755102*x*exp(-8*x/7)
 + 2.74285714285714*exp(-8*x/7) 
+ 13.7142857142857*exp(-24*x/7)*sin(12*x/7) 
- 6.85714285714286*exp(-24*x/7)*cos(12*x/7)
segunda derivada: 
3.58250728862974*x*exp(-8*x/7) 
- 6.26938775510204*exp(-8*x/7) 
- 35.265306122449*exp(-24*x/7)*sin(12*x/7) 
+ 47.0204081632653*exp(-24*x/7)*cos(12*x/7)

La gráfica requiere la evaluación las funciones, que por simplicidad de evaluación, su formas simbólicas se convierten a su forma ‘lambda’.

Con la gráfica se verifica que la raíz de dp(x)/dx (en naranja) pasa por el máximo y mínimo de p(x) (en azul).

que se obtienen con las siguientes instrucciones en Python:

# 1ra Evaluación I Término 2010
# tema 2. encendido tv
# Tarea: aplicar el método de Newton-Raphson
# solo se muestra la función y sus derivadas 1 y 2
import numpy as np
import sympy as sym
import matplotlib.pyplot as plt

# función bajo análisis en forma simbólica
x = sym.Symbol('x')
pxs = (1/2.5)*(-10*sym.sin(12*x/7)*sym.exp(-24*x/7) \
               + (48*x/7)*sym.exp(-8*x/7)+0.8)

# derivadas
dpxs = pxs.diff(x,1)
d2pxs = pxs.diff(x,2)
d2pxs = sym.expand(d2pxs)

# SALIDA
print('primera derivada: ')
print(dpxs)
print('segunda derivada: ')
print(d2pxs)

# conversion a lambda
pxn = sym.utilities.lambdify(x,pxs, 'numpy')
dpxn = sym.utilities.lambdify(x,dpxs, 'numpy')
d2pxn = sym.utilities.lambdify(x,d2pxs, 'numpy')

# observar gráfica
a = 0
b = 4
muestras = 51
tolera = 0.0001

xi = np.linspace(a,b, muestras)
pxi = pxn(xi)
dpxi = dpxn(xi)
d2pxi = d2pxn(xi)

# Gráfica
plt.plot(xi,pxi, label = 'pxi')
plt.plot(xi,dpxi, label = 'dpxi')
plt.plot(xi,d2pxi, label = 'd2pxi')
plt.axhline(0)
plt.legend()
plt.show()

literal b

Usando el método de Newton-Raphson a partir de la primera y segunda derivada según lo planteado, usando x0=0,se tiene:

f(x) = -3.13469387755102 x e^{(-8 x/7)} +2.74285714285714 e^{(-8 x/7)} + 13.7142857142857 e^{(-24 x/7)} \sin\Big(\frac{12x}{7}\Big) - 6.85714285714286 e^{(-24x/7)} \cos\Big(\frac{12x}{7}\Big) f'(x) = 3.58250728862974 x e^{(- 8 x/7)} - 6.26938775510204 e^{(- 8 x/7)} - 35.265306122449 e^{(-24x/7)} \sin \Big(\frac{12x}{7}\Big) + 47.0204081632653 e^{(-24x/7)} \cos\Big(\frac{12x}{7}\Big)

itera = 0, x0 = 0

f(0) = -3.13469387755102 (0) e^{(-8 (0)/7)} +2.74285714285714 e^{(-8 (0)/7)} + 13.7142857142857 e^{(-24 (0)/7)} \sin\Big(\frac{12(0)}{7}\Big) - 6.85714285714286 e^{(-24(0)/7)} \cos\Big(\frac{12(0)}{7}\Big) = -4.1143 f'(0) = 3.58250728862974 (0) e^{(- 8 (0)/7)} - 6.26938775510204 e^{(- 8(0)/7)} - 35.265306122449 e^{(-24(0)/7)} \sin \Big(\frac{12(0)}{7}\Big) + 47.0204081632653 e^{(-24(0)/7)} \cos\Big(\frac{12(0)}{7}\Big) = 40.751 x_1 = 0 - \frac{-4.1143}{40.751} =0.101 error = | 0.101-0 |=0.101

itera = 1

f(0.101) = -3.13469387755102 (0.101) e^{(-8 (0.101)/7)} +2.74285714285714 e^{(-8 (0.101)/7)} + 13.7142857142857 e^{(-24 (0.101)/7)} \sin\Big(\frac{12(0.101)}{7}\Big) - 6.85714285714286 e^{(-24(0.101)/7)} \cos\Big(\frac{12(0.101)}{7}\Big) = -0.9456 f'(0.101) = 3.58250728862974 (0.101) e^{(- 8 (0.101)/7)} - 6.26938775510204 e^{(- 8 (0.101)/7)} - 35.265306122449 e^{(-24(0.101)/7)} \sin \Big(\frac{12(0.101)}{7}\Big) + 47.0204081632653 e^{(-24(0.101)/7)} \cos\Big(\frac{12(0.101)}{7}\Big) =23.2054 x_2 = 0.101 - \frac{-0.9456}{23.2054} =0.1417 error = | 0.1417-0.101 |=0.0407

itera = 2

f(0.1417) = -3.13469387755102 (0.1417) e^{(-8 (0.1417)/7)} +2.74285714285714 e^{(-8 (0.1417)/7)} + 13.7142857142857 e^{(-24 (0.1417)/7)} \sin\Big(\frac{12(0.1417)}{7}\Big) - 6.85714285714286 e^{(-24(0.1417)/7)} \cos\Big(\frac{12(0.1417)}{7}\Big) = -0.11005 f'(0.1417) = 3.58250728862974 (0.1417) e^{(- 8 (0.1417)/7)} - 6.26938775510204 e^{(- 8 (0.1417)/7)} - 35.265306122449 e^{(-24(0.1417)/7)} \sin \Big(\frac{12(0.1417)}{7}\Big) + 47.0204081632653 e^{(-24(0.1417)/7)} \cos\Big(\frac{12(0.1417)}{7}\Big) = 0.17957 x_3 = 0.1417 - \frac{-0.11005}{0.17957} =0.14784 error = | 0.14784- 0.1417 |=0.0061287

se observa que el error disminuye en cada iteración, por lo que el método converge.

Se continúan las operaciones con el algoritmo obteniendo:

i ['xi', 'fi', 'dfi', 'xnuevo', 'tramo']
0 [ 0.     -4.1143 40.751   0.101   0.101 ]
1 [ 0.101  -0.9456 23.2054  0.1417  0.0407]
2 [ 1.4171e-01 -1.1005e-01  1.7957e+01  1.4784e-01  6.1287e-03]
3 [ 1.4784e-01 -2.1916e-03  1.7245e+01  1.4797e-01  1.2708e-04]
4 [ 1.4797e-01 -9.2531e-07  1.7231e+01  1.4797e-01  5.3701e-08]
raíz en:  0.1479664890264113

literal c

la otra raíz se encuentra con x0=1

i ['xi', 'fi', 'dfi', 'xnuevo', 'tramo']
0 [ 1.      0.3471 -2.207   1.1573  0.1573]
1 [ 1.1573  0.0539 -1.5338  1.1924  0.0352]
2 [ 1.1924  0.0024 -1.397   1.1941  0.0017]
3 [ 1.1941e+00  5.7065e-06 -1.3904e+00  1.1942e+00  4.1041e-06]
raíz en:  1.1941511721360376

Instrucciones en Python

# 1Eva_IT2010_T2_MN Uso de televisores

import numpy as np
import matplotlib.pyplot as plt

def newton_raphson(fx,dfx,xi, tolera, iteramax=100, vertabla=False, precision=4):
    '''
    funciónx y fxderiva en forma numérica lambda
    xi es el punto inicial de búsqueda
    '''
    itera=0
    tramo = abs(2*tolera)
    if vertabla==True:
        print('i', ['xi','fi','dfi', 'xnuevo', 'tramo'])
        np.set_printoptions(precision)
    while (tramo>=tolera and itera<iteramax):
        fi = fx(xi)
        dfi = dfx(xi)
        xnuevo = xi - fi/dfi
        tramo = abs(xnuevo-xi)
        if vertabla==True:
            print(itera,np.array([xi,fi,dfi,xnuevo,tramo]))
        xi = xnuevo
        itera = itera + 1
    if itera>=iteramax:
        xi = np.nan
        print('itera: ',itera, 'No converge,se alcanzó el máximo de iteraciones')
    return(xi)

# INGRESO
fx  = lambda x: -3.13469387755102*x*np.exp(-8*x/7) \
      + 2.74285714285714*np.exp(-8*x/7) \
      + 13.7142857142857*np.exp(-24*x/7)*np.sin(12*x/7) \
      - 6.85714285714286*np.exp(-24*x/7)*np.cos(12*x/7)
dfx = lambda x: (3.58250728862974*x - 6.26938775510204 \
                 - 35.265306122449*np.exp(-16*x/7)*np.sin(12*x/7) \
                 + 47.0204081632653*np.exp(-16*x/7)*np.cos(12*x/7))*np.exp(-8*x/7)

x0 = 0.5
tolera = 0.0001

# PROCEDIMIENTO
respuesta = newton_raphson(fx,dfx,x0, tolera, vertabla=True)
# SALIDA
print('raíz en: ', respuesta)

s1Eva_IT2010_T1_MN Demanda y producción sin,log

Ejercicio: 1Eva_IT2010_T1_MN Demanda y producción sin,log

Desarrollo Analítico

Para la demanda, el intervalo de existencia es [0,3]

demanda(t) = sin(t)

Para la oferta, el intervalo de existencia inicia en 1, limitado por la demanda [1,3]

oferta(t) = ln(t)

la oferta satisface la demanda cuando ambas son iguales

demanda(t) = oferta(t) sin(t) = ln(t)

por lo que el tiempo t se encuentra con algún método para determinar la raíz de:

sin(t) - ln(t) = 0 f(t) = sin(t) - ln(t)

Observe que las curvas de oferta y demanda se interceptan en el mismo punto en el eje x que la función f(t).

Para encontrar el valor de intersección de f(t) se propone usar el método de la bisección, en el intervalo [1,3]

itera =  0

a = 1, b =3

c=\frac{1+3}{2} = 2 f(1) = sin(1) - ln(1) = 0.8415 f(3) = sin(3) - ln(3) =-0.9575 f(2) = sin(2) - ln(2) =0.2162

cambio de signo a la derecha

a =c = 2 , b = 3 tramo = |3-2| =1

itera =  1

a = 2, b =3

c=\frac{2+3}{2} = 2.5 f(2) = 0.2162 f(3) =-0.9575 f(2.5) = sin(2.5) - ln(2.5) = -0.3178

cambio de signo a la izquierda

a= 2 , b = c = 2.5 tramo = |2.5-2| = 0.5

itera =  2

a = 2, b =2.5

c=\frac{2+2.5}{2} = 2.25 f(2) = 0.2162 f(2.5) = -0.3178 f(2.25) = sin(2.25) - ln(2.25) = -0.3178

cambio de signo a la izquierda

a= 2 , b = c = 2.25 tramo = |2.25-2| = 0.25

El resto de las iteraciones se continúan con el algoritmo,

encontrando la raíz en 2.219 usando tolerancia de 0.001


Algoritmo en Python

Desarrollo con el método de la Bisección usando el algoritmo:

método de Bisección
i ['a', 'c', 'b'] ['f(a)', 'f(c)', 'f(b)']
   tramo
0 [1, 2.0, 3] [ 0.8415 -0.9575  0.2162]
   1.0
1 [2.0, 2.5, 3] [ 0.2162 -0.9575 -0.3178]
   0.5
2 [2.0, 2.25, 2.5] [ 0.2162 -0.3178 -0.0329]
   0.25
3 [2.0, 2.125, 2.25] [ 0.2162 -0.0329  0.0965]
   0.125
4 [2.125, 2.1875, 2.25] [ 0.0965 -0.0329  0.033 ]
   0.0625
5 [2.1875, 2.21875, 2.25] [ 0.033  -0.0329  0.0004]
   0.03125
6 [2.21875, 2.234375, 2.25] [ 0.0004 -0.0329 -0.0162]
   0.015625
7 [2.21875, 2.2265625, 2.234375] [ 0.0004 -0.0162 -0.0079]
   0.0078125
8 [2.21875, 2.22265625, 2.2265625] [ 0.0004 -0.0079 -0.0037]
   0.00390625
9 [2.21875, 2.220703125, 2.22265625] [ 0.0004 -0.0037 -0.0017]
   0.001953125
10 [2.21875, 2.2197265625, 2.220703125] [ 0.0004 -0.0017 -0.0007]
   0.0009765625
raíz en:  2.2197265625

Instrucciones en Python

# 1Eva_IT2010_T1_MN Demanda y producción sin,log
import numpy as np
import matplotlib.pyplot as plt

def biseccion(fx,a,b,tolera,iteramax = 20, vertabla=False, precision=4):
    '''
    Algoritmo de Bisección
    Los valores de [a,b] son seleccionados
    desde la gráfica de la función
    error = tolera
    '''
    fa = fx(a)
    fb = fx(b)

    itera = 0
    tramo = np.abs(b-a)
    if vertabla==True:
        print('método de Bisección')
        print('i', ['a','c','b'],[ 'f(a)', 'f(c)','f(b)'])
        print('  ','tramo')
        np.set_printoptions(precision)
    while (tramo>=tolera and itera<=iteramax):
        c = (a+b)/2
        fc = fx(c)
        cambia = np.sign(fa)*np.sign(fc)
        if vertabla==True:
            print(itera,[a,c,b],np.array([fa,fb,fc]))
        if (cambia<0):
            b = c
            fb = fc
        else:
            a = c
            fa = fc
        tramo = np.abs(b-a)
        if vertabla==True:
            print('  ',tramo)
        itera = itera + 1
    respuesta = c
    # Valida respuesta
    if (itera>=iteramax):
        respuesta = np.nan
    return(respuesta)

# INGRESO
fx  = lambda t: np.sin(t) - np.log(t)

a = 1
b = 3
tolera = 0.001

# PROCEDIMIENTO
respuesta = biseccion(fx,a,b,tolera,vertabla=True)
# SALIDA
print('raíz en: ', respuesta)

# GRAFICA
ad = 0
bd = 3
# intervalo oferta
# considerando que no existe oferta negativa
ao = 1
bo = 3
muestras = 21

demanda = lambda t: np.sin(t)
oferta = lambda t: np.log(t)
f = lambda t: demanda(t)-oferta(t)

# PROCEDIMIENTO
tid = np.linspace(ad,bd,muestras)
demandai = demanda(tid)

tio = np.linspace(ao,bo,muestras)
ofertai = oferta(tio)

fi = f(tio)

# SALIDA
plt.plot(tid,demandai, label='demanda')
plt.plot(tio,ofertai, label ='oferta')
plt.plot(tio,fi,label='f(t)= demanda-oferta')
plt.axhline(0,color='black')
plt.axvline(2.2185, color = 'magenta')
plt.xlabel('tiempo')
plt.ylabel('unidades')
plt.legend()
plt.grid()
plt.show()

s1Eva_IT2009_T2 Materiales y Productos 3×4

Ejercicio: 1Eva_IT2009_T2 Materiales y Productos 3×4

Con los datos de la tabla se plantean las ecuaciones:

P1 P2 P3 P4
M1 0.2 0.5 0.4 0.2
M2 0.3 0 0.5 0.6
M3 0.4 0.5 0.1 0.2

La cantidad disponible de cada material es: 10, 12, 15 Kg respectivamente, los cuales deben usarse completamente.

1. Plantear el sistema de ecuaciones

0.2 x_0 + 0.5 x_1 + 0.4 x_2 + 0.2 x_3 = 10 0.3 x_0 + 0 x_1 + 0.5 x_2 + 0.6 x_3 = 12 0.4 x_0 + 0.5 x_1 + 0.1 x_2 + 0.2 x_3 = 15

Observe que hay más incógnitas que ecuaciones.

Para equiparar las ecuaciones con el número de incógnitas, podríamos suponer que uno de los productos NO se fabricará. por ejemplo el producto x3 que podría hacerse igual a cero. Supone que la variable libre es x3 .

Para mantener la forma de las ecuaciones para otros valores de x3, se pasa la variable y su coeficiente a la derecha.

\begin{cases} 0.2 x_0 + 0.5 x_1 + 0.4 x_2 = 10 - 0.2 x_3 \\ 0.3 x_0 + 0 x_1 + 0.5 x_2 = 12 - 0.6 x_3 \\ 0.4 x_0 + 0.5 x_1 + 0.1 x_2 = 15 - 0.2 x_3 \end{cases}

Para analizar el ejercicio, se supondrá que el valor de x3 = 0, lo que permite usar el modelo del problema como A.X=B .En caso de que x3 sea diferente de cero,  el vector B modifica, y se puede proceder con el sistema de ecuaciones.

2. Convertir a la forma matricial AX = B

Siendo así, suponiendo que x3 = 0, el ejercicio se puede desarrollar usando:

\begin{pmatrix} 0.2 && 0.5 &&0.4 &&10 \\ 0.3 && 0. && 0.5 && 12.\\ 0.4 && 0.5 && 0.1 && 15. \end{pmatrix}

que de debe pivotear por filas antes de aplicar cualquier método de solución, primero se intercambian la primera y última filas para que el primer valor de la diagonal sea el mayor en la columna.

\begin{pmatrix} 0.4 && 0.5 && 0.1 && 15. \\ 0.3 && 0. && 0.5 && 12. \\0.2 && 0.5 &&0.4 &&10 \end{pmatrix}

luego se repite el proceso a partir de la diagonal en la fila segunda, columna segunda, que al tener un valor de 5  en la tercera fila que es mayor que 0, se intercambia la fila segunda con la tercera

\begin{pmatrix} 0.4 && 0.5 && 0.1 && 15. \\0.2 && 0.5 &&0.4 &&10 \\ 0.3 && 0. && 0.5 && 12. \end{pmatrix}

Para el proceso de eliminación hacia adelante se tiene:

para pivote[0,0] = 0.4,

fila = 0 vs fila 1:
pivote = 0.4, factor = 0.2/0.4 = 0.5

\begin{pmatrix} 0.4 && 0.5 && 0.1 && 15. \\0 && 0.25 &&0.35 &&2.5 \\ 0.3 && 0. && 0.5 && 12. \end{pmatrix}

fila = 0 vs fila 2:
pivote = 0.4, factor = 0.3/0.4 = 0.75

\begin{pmatrix} 0.4 && 0.5 && 0.1 && 15. \\0 && 0.25 &&0.35 &&2.5 \\ 0 && -0.375 && 0.425 && 0.75 \end{pmatrix}

y luego para pivote [1,1]

fila = 1 vs fila 2:

pivote = 0.25, factor =-0.375/0.25 = -1.5

\begin{pmatrix} 0.4 && 0.5 && 0.1 && 15. \\0 && 0.25 &&0.35 &&2.5 \\ 0 && 0. && 0.95 && 4.5 \end{pmatrix}

Para eliminación hacia atrás los factores serán:

fila 2 pivote: 0.95
factor: 0.368421052631579 para fila: 1
factor: 0.10526315789473685 para fila: 0

\begin{pmatrix} 0.4 && 0.5 && 0 && 14.52631579 \\0 && 0.25 &&0 &&0.84210526 \\ 0 && 0. && 0.95 && 4.5 \end{pmatrix}

fila 1 pivote: 0.25
factor: 2.0 para fila: 0

\begin{pmatrix} 0.4 && 0 && 0 && 12.84210526 \\0 && 0.25 &&0 &&0.84210526 \\ 0 && 0. && 0.95 && 4.5 \end{pmatrix}

lo que da como resultado:

\begin{pmatrix} 1 && 0 && 0 && 32.10526316 \\0 && 1 &&0 &&3.36842105 \\ 0 && 0 && 1 && 4.73684211 \end{pmatrix}

que da como solución:

x= [32.10526316, 3.36842105 , 4.73684211]

Algoritmo en Python

Para el algoritmo se puede empezar con:

A = np.array([[0.2, 0.5, 0.4],
              [0.3, 0.0, 0.5],
              [0.4, 0.5, 0.1]])
B = np.array([10, 12, 15],dtype=float)

que luego armar el algoritmo y su ejecución, obtendría una solución semejante:

Matriz aumentada
[[ 0.2  0.5  0.4 10. ]
 [ 0.3  0.   0.5 12. ]
 [ 0.4  0.5  0.1 15. ]]
Pivoteo parcial:
  1 intercambiar filas:  0 y 2
  2 intercambiar filas:  1 y 2
[[ 0.4  0.5  0.1 15. ]
 [ 0.2  0.5  0.4 10. ]
 [ 0.3  0.   0.5 12. ]]
Elimina hacia adelante:
 fila 0 pivote:  0.4
   factor:  0.5  para fila:  1
   factor:  0.7499999999999999  para fila:  2
 fila 1 pivote:  0.25
   factor:  -1.4999999999999998  para fila:  2
 fila 2 pivote:  0.95
[[ 0.4   0.5   0.1  15.  ]
 [ 0.    0.25  0.35  2.5 ]
 [ 0.    0.    0.95  4.5 ]]
Elimina hacia Atras:
 fila 2 pivote:  0.95
   factor:  0.368421052631579  para fila:  1
   factor:  0.10526315789473685  para fila:  0
 fila 1 pivote:  0.25
   factor:  2.0  para fila:  0
 fila 0 pivote:  0.4
[[ 1.          0.          0.         32.10526316]
 [ 0.          1.          0.          3.36842105]
 [ 0.          0.          1.          4.73684211]]
solución X: 
[32.10526316  3.36842105  4.73684211]
>>>

Instrucciones en Python

#1Eva_IT2009_T2 Materiales y Productos 3×4
# Método de Gauss-Jordan
# Solución a Sistemas de Ecuaciones
# de la forma A.X=B

import numpy as np

def pivoteafila(A,B,vertabla=False):
    '''
    Pivotea parcial por filas
    Si hay ceros en diagonal es matriz singular,
    Tarea: Revisar si diagonal tiene ceros
    '''
    A = np.array(A,dtype=float)
    B = np.array(B,dtype=float)
    # Matriz aumentada
    nB = len(np.shape(B))
    if nB == 1:
        B = np.transpose([B])
    AB  = np.concatenate((A,B),axis=1)
    
    if vertabla==True:
        print('Matriz aumentada')
        print(AB)
        print('Pivoteo parcial:')
    
    # Pivoteo por filas AB
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    
    # Para cada fila en AB
    pivoteado = 0
    for i in range(0,n-1,1):
        # columna desde diagonal i en adelante
        columna = np.abs(AB[i:,i])
        dondemax = np.argmax(columna)
        
        # dondemax no es en diagonal
        if (dondemax != 0):
            # intercambia filas
            temporal = np.copy(AB[i,:])
            AB[i,:] = AB[dondemax+i,:]
            AB[dondemax+i,:] = temporal

            pivoteado = pivoteado + 1
            if vertabla==True:
                print(' ',pivoteado, 'intercambiar filas: ',i,'y', dondemax+i)
                
    if vertabla==True:
        if pivoteado==0:
            print('  Pivoteo por filas NO requerido')
        else:
            print(AB)
    return(AB)

def gauss_eliminaAdelante(AB, vertabla=False,lu=False,casicero = 1e-15):
    ''' Gauss elimina hacia adelante, a partir de,
    matriz aumentada y pivoteada.
    Para respuesta en forma A=L.U usar lu=True entrega[AB,L,U]
    '''
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    L = np.identity(n,dtype=float) # Inicializa L
    if vertabla==True:
        print('Elimina hacia adelante:')
    for i in range(0,n,1):
        pivote = AB[i,i]
        adelante = i+1
        if vertabla==True:
            print(' fila',i,'pivote: ', pivote)
        for k in range(adelante,n,1):
            if (np.abs(pivote)>=casicero):
                factor = AB[k,i]/pivote
                AB[k,:] = AB[k,:] - factor*AB[i,:]

                L[k,i] = factor # llena L
                
                if vertabla==True:
                    print('   factor: ',factor,' para fila: ',k)
                print(AB)
            else:
                print('  pivote:', pivote,'en fila:',i,
                      'genera division para cero')
    respuesta = AB
    if vertabla==True:
        print(AB)
    if lu==True:
        U = AB[:,:n-1]
        respuesta = [AB,L,U]
    return(respuesta)

def gauss_eliminaAtras(AB, vertabla=False, precision=5, casicero = 1e-15):
    ''' Gauss-Jordan elimina hacia atras
    Requiere la matriz triangular inferior
    Tarea: Verificar que sea triangular inferior
    '''
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    
    ultfila = n-1
    ultcolumna = m-1
    if vertabla==True:
        print('Elimina hacia Atras:')
        
    for i in range(ultfila,0-1,-1):
        pivote = AB[i,i]
        atras = i-1  # arriba de la fila i
        if vertabla==True:
            print(' fila',i,'pivote: ', pivote)
            
        for k in range(atras,0-1,-1):
            if (np.abs(AB[k,i])>=casicero):
                factor = AB[k,i]/pivote
                AB[k,:] = AB[k,:] - factor*AB[i,:]
                
                if vertabla==True:
                    print('   factor: ',factor,' para fila: ',k)
            else:
                print('  pivote:', pivote,'en fila:',i,
                      'genera division para cero')
 
        AB[i,:] = AB[i,:]/AB[i,i] # diagonal a unos
    X = np.copy(AB[:,ultcolumna])
    
    if vertabla==True:
        print(AB)
    return(X)

# PROGRAMA ------------------------
# INGRESO
A = np.array([[0.2, 0.5, 0.4],
              [0.3, 0.0, 0.5],
              [0.4, 0.5, 0.1]])
B = np.array([10, 12, 15],dtype=float)

# PROCEDIMIENTO
AB = pivoteafila(A,B,vertabla=True)

AB = gauss_eliminaAdelante(AB,vertabla=True)

X = gauss_eliminaAtras(AB,vertabla=True)

# SALIDA
print('solución X: ')
print(X)

Encontrada la solución, modifique el algoritmo para calcular B en función de x3, pregunte el valor al inicio, y vuelva a calcular.

x3 = float(input('cantidad a producir de cuarto producto: ')

Observe el rango para x3, por ejemplo que debe ser mayor o igual que cero, pues no hay producción negativa. De producir solamente ése un producto, el valor máximo de unidades a obtener no superaría lo posible con la cantidad de materiales disponible.

Ejemplo:

x3 = 1
B3 = [0.2,0.6,0.2]
Bnuevo = B - x3*B3

>>> Bnuevo
array([  9.8, 11.4,  14.8])

Y se vuelve a generar el sistema A.X=Bnuevo

Observación: Algunos productos se fabrican por unidades, no necesariamente por peso o volumen. ¿comentarios al respecto?

 

s1Eva_IT2009_T1 Demanda de un producto alcanza la producción

Ejercicio: 1Eva_IT2009_T1 Demanda de un producto alcanza la producción

Desarrollo analítico

– igualar la ecuación al valor buscado, 80

200 t e^{-0.75t} = 80

– forma estándar de la ecuación para el método f(x) = 0:

f(t) = 200 t e^{-0.75t} - 80

– derivada de la ecuación

f'(t) = 200 e^{-0.75t} + 200 t (-0.75) e^{-0.75t} f'(t) = 200 e^{-0.75t}(1-0.75t)

– fórmula del método de Newton-Raphson

t_{i+1} = t_i - \frac{f(t)}{f'(t)}

– Punto inicial. Como la variable es t, tiempo, el rango de análisis es t>0
El valor inicial de búsqueda se selecciona t0 = 1

iteración 0:

f(1) = 200 (1) e^{-0.75(1)} - 80 =14.4733 f'(1) = 200 e^{-0.75(1)}(1-0.75(1)) = 23.6183 t_{1} = 1 - \frac{14.4733}{23.6183} =0.3872 error = |0.3872 - 1| = 0.6128

iteración 1:

f(0.3872)= 200 (0.3872) e^{-0.75(0.3872)} - 80 = -22.0776 f'(0.3872 )= 200 e^{-0.75(0.3872)}(1-0.75(0.3872)) = 106.1511 t_{2} = 0.3872 - \frac{-22.0776}{106.1511} = 0.5952 error = |0.5952- 0.3872| = 0.208

iteración 2:

f(0.5952)=200 (0.5952) e^{-0.75(0.5952)} - 80 = -3.8242 f'(0.5952) = 200 e^{-0.75(0.5952)}(1-0.75(0.5952)) = 70.855 t_{3} = 0.5952 - \frac{-3.8242}{70.855} = 0.64916

error = |0.64916-0.5952| = 0.053972

tabla de iteraciones

i ['xi', 'fi', 'dfi', 'xnuevo', 'tramo']
0 [ 1.     14.4733 23.6183  0.3872  0.6128]
1 [  0.3872 -22.0776 106.1511   0.5952   0.208 ]
2 [ 5.9518e-01 -3.8242e+00  7.0855e+01  6.4916e-01  5.3972e-02]
3 [ 6.4916e-01 -2.1246e-01  6.3069e+01  6.5252e-01  3.3686e-03]
4 [ 6.5252e-01 -7.9031e-04  6.2600e+01  6.5254e-01  1.2625e-05]
5 [ 6.5254e-01 -1.1069e-08  6.2599e+01  6.5254e-01  1.7683e-10]
raíz en:  0.6525363029069534

Se obtiene el valor de la raíz con 5 iteraciones, y un error de 1.2625e-05


Desarrollo con Python

# 1Eva_IT2009_T1 Demanda de un producto alcanza la producción

import numpy as np
import matplotlib.pyplot as plt

def newton_raphson(fx,dfx,xi, tolera, iteramax=100, vertabla=False, precision=4):
    '''
    fx y dfx en forma numérica lambda
    xi es el punto inicial de búsqueda
    '''
    itera=0
    tramo = abs(2*tolera)
    if vertabla==True:
        print('método de Newton-Raphson')
        print('i', ['xi','fi','dfi', 'xnuevo', 'tramo'])
        np.set_printoptions(precision)
    while (tramo>=tolera):
        fi = fx(xi)
        dfi = dfx(xi)
        xnuevo = xi - fi/dfi
        tramo = abs(xnuevo-xi)
        if vertabla==True:
            print(itera,np.array([xi,fi,dfi,xnuevo,tramo]))
        xi = xnuevo
        itera = itera + 1

    if itera>=iteramax:
        xi = np.nan
        print('itera: ',itera, 'No converge,se alcanzó el máximo de iteraciones')

    return(xi)

# INGRESO
fx  = lambda t: 200*t*np.exp(-0.75*t) - 80
dfx = lambda t: 200*np.exp(-0.75*t) + 200*t*(-0.75)*np.exp(-0.75*t)

#fx  = lambda t: 200*np.exp(-0.75*t) + 200*t*(-0.75)*np.exp(-0.75*t)
#dfx = lambda t: (112.5*t - 300.0)*np.exp(-0.75*t)

x0 = 1
tolera = 0.00001

# PROCEDIMIENTO
respuesta = newton_raphson(fx,dfx,x0, tolera, vertabla=True)
# SALIDA
print('raíz en: ', respuesta)

Para la gráfica se añade:

# grafica
a = 0
b = 2
muestras = 21

xi = np.linspace(a,b,muestras)
fi = fx(xi)
plt.plot(xi,fi)
plt.axhline(0)
plt.xlabel('x')
plt.ylabel('f(x)')
plt.show()

Literal b

Para el caso de encontrar el máximo se usaría la expresión fb(t) cuando f'(t)= 0.

Con lo que para el algoritmo la expresión nueva f(t) es :

y fb‘(t) es f''(t):

f_b(t) = f'(t) = 200 e^{-0.75t} + 200 t (-0.75) e^{-0.75t} f_b'(t) = f''(t) = (112.5t-300)e^{-0.75t}

se desarrolla las expresiones con Sympy :

>>> import sympy as sym
>>> t = sym.Symbol('t')
>>> f = 200*t*sym.exp(-0.75*t)-80
>>> sym.diff(f,t,1)
-150.0*t*exp(-0.75*t) + 200*exp(-0.75*t)
>>> sym.diff(f,t,2)
(112.5*t - 300.0)*exp(-0.75*t)
>>> 

Se actualiza el algoritmo con las funciones:

fx  = lambda t: 200*np.exp(-0.75*t) + 200*t*(-0.75)*np.exp(-0.75*t)
dfx = lambda t: (112.5*t - 300.0)*np.exp(-0.75*t)

y se obtiene como resultado:

método de Newton-Raphson
i ['xi', 'fi', 'dfi', 'xnuevo', 'tramo']
0 [  1.      23.6183 -88.5687   1.2667   0.2667]
1 [  1.2667   3.8674 -60.9117   1.3302   0.0635]
2 [ 1.3302e+00  1.7560e-01 -5.5445e+01  1.3333e+00  3.1671e-03]
3 [ 1.3333e+00  4.1611e-04 -5.5183e+01  1.3333e+00  7.5406e-06]
raíz en:  1.3333333332906878

 

s1Eva_IIT2008_T3_MN Ganancia en inversión

Ejercicio: 1Eva_IIT2008_T3_MN Ganancia en inversión

Se dispone de los datos (x, f(x)), en donde x es un valor de inversión y f(x) es un valor de ganancia, ambos en miles de dólares.

xi = np.array([3.2 , 3.8 , 4.2 , 4.5 ]) 
fi = np.array([5.12, 6.42, 7.25, 6.85])

Los datos se usan junto al modelo propuesto:

f(x) = a_1 x^3 + a_2 x^2 + a_3 x + a_4

generando las expresiones del sistema de ecuaciones:

a_1 (3.2)^3 + a_2 (3.2)^2 + a_3 (3.2) + a_4 = 5.12 a_1 (3.8)^3 + a_2 (3.8)^2 + a_3 (3.8) + a_4 = 6.42 a_1 (4.2)^3 + a_2 (4.2)^2 + a_3 (4.2) + a_4 = 7.25 a_1 (4.5)^3 + a_2 (4.5)^2 + a_3 (4.5) + a_4 = 6.85

Se convierte a la forma Ax=B
\begin{bmatrix} (3.2)^3 && (3.2)^2 && (3.2) && 1 \\ (3.8)^3 && (3.8)^2 && (3.8) && 1 \\ (4.2)^3 && (4.2)^2 && (4.2) && 1 \\ (4.5)^3 && (4.5)^2 && (4.5) && 1 \end{bmatrix} . \begin{bmatrix} a_1 \\ a_2 \\ a_3 \\ a_4 \end{bmatrix} = \begin{bmatrix} 5.12 \\ 6.42 \\ 7.25 \\6.85 \end{bmatrix}

Se crea la matriz aumentada

\begin{bmatrix} (3.2)^3 && (3.2)^2 && (3.2) && 1 && 5.12\\ (3.8)^3 && (3.8)^2 && (3.8) && 1 && 6.42 \\ (4.2)^3 && (4.2)^2 && (4.2) && 1 && 7.25 \\ (4.5)^3 && (4.5)^2 && (4.5) && 1 && 6.85 \end{bmatrix}

Se pivotea por filas:

\begin{bmatrix} (4.5)^3 && (4.5)^2 && (4.5) && 1 && 6.85 \\ (4.2)^3 && (4.2)^2 && (4.2) && 1 && 7.25 \\ (3.8)^3 && (3.8)^2 && (3.8) && 1 && 6.42 \\ (3.2)^3 && (3.2)^2 && (3.2) && 1 && 5.12 \end{bmatrix}

Como se pide un método directo, se inicia con el algoritmo de eliminación hacia adelante con factor para cada fila a partir de la diagonal.

\begin{bmatrix} (4.5)^3 && (4.5)^2 && (4.5) \\ (4.2)^3 - (4.5)^3\frac{(4.2)^3}{(4.5)^3} && (4.2)^2 - (4.5)^2\frac{(4.2)^3}{(4.5)^3} && (4.2) - (4.5)\frac{(4.2)^3}{(4.5)^3} \\ (3.8)^3 - (4.5)^3\frac{(3.8)^3}{(4.5)^3} && (3.8)^2 - (4.5)^2\frac{(3.8)^3}{(4.5)^3} && (3.8) -(4.5)\frac{(3.8)^3}{(4.5)^3} \\ (3.2)^3 - (4.5)^3\frac{(3.2)^3}{(4.5)^3} && (3.2)^2 -(4.5)^2\frac{(3.2)^3}{(4.5)^3} && (3.2) - (4.5)\frac{(3.2)^3}{(4.5)^3} \end{bmatrix}

continua a la derecha de la matriz:

\begin{bmatrix} 1 && 6.85 \\ 1 - 1\frac{(4.2)^3}{(4.5)^3} && 7.25 - 6.85\frac{(4.2)^3}{(4.5)^3} \\ 1 -1\frac{(3.8)^3}{(4.5)^3} && 6.42 - 6.85\frac{(3.8)^3}{(4.5)^3}\\1 -1\frac{(3.2)^3}{(4.5)^3} && 5.12-6.85\frac{(3.2)^3}{(4.5)^3} \end{bmatrix}
[[91.125  20.25   4.5    1.     6.85 ]
 [ 0.      1.176  0.541  0.186  1.680]
 [ 0.      2.246  1.090  0.397  2.295]
 [ 0.      2.958  1.581  0.640  2.656]]
Elimina hacia adelante
[[91.125  20.250  4.500  1.000  6.850]
 [ 0.      1.176  0.541  0.186  1.680]
 [ 0.      0.     0.056  0.040 -0.915]
 [ 0.      0.     0.220  0.170 -1.571]]
Elimina hacia adelante
[[91.125  20.250  4.500  1.000  6.850]
 [ 0.      1.176  0.541  0.186  1.680]
 [ 0.      0.000  0.056  0.040 -0.915]
 [ 0.      0.000  0.000  0.010  2.006]]
Elimina hacia adelante
[[91.125  20.250  4.500  1.000  6.850]
 [ 0.      1.176  0.541  0.186  1.680]
 [ 0.      0.     0.056  0.040 -0.915]
 [ 0.      0.     0.     0.010  2.006]]
Elimina hacia atras
[[1. 0. 0. 0.   -3.67490842]
 [0. 1. 0. 0.   41.06730769]
 [0. 0. 1. 0. -149.92086081]
 [0. 0. 0. 1.  184.75692308]]
el vector solución X es:
[[  -3.67490842]
 [  41.06730769]
 [-149.92086081]
 [ 184.75692308]]

verificar que A.X = B
[[6.85]
 [7.25]
 [6.42]
 [5.12]]

con lo que el polinomio buscado es:

f(x) = -3.67490842 x^3 + 41.06730769 x^2 + -149.92086081 x + 184.75692308

que genera la siguiente gráfica:

para encontrar la cantidad necesaria a invertir y obtener 6.0 de ganancia en f(x):

6.0 = -3.67490842 x^3 + 41.06730769 x^2 + -149.92086081 x + 184.75692308

que para usar en el algoritmo se realiza se reordena como g(x) = 0

-3.67490842 x^3 + 41.06730769 x^2 +

-149.92086081 x + 184.75692308 - 6.0 = 0
y se aplica la búsqueda de raices en el rango [a, b] que de la gráfica se estima en [3.2, 3.8]

La ejecución del algoritmo de búsqueda queda como tarea.


Algoritmo en python para obtener la gráfica y respuesta a la matriz:

# Método de Gauss-Jordan ,
# Recibe las matrices A,B
# presenta solucion X que cumple: A.X=B
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
puntos = np.array([[3.2, 5.12],
                   [3.8, 6.42],
                   [4.2, 7.25],
                   [4.5, 6.85]])

A = np.array([[4.5**3 , 4.5**2 , 4.5 , 1],
              [4.2**3 , 4.2**2 , 4.2 , 1],
              [3.8**3 , 3.8**2 , 3.8 , 1],
              [3.2**3 , 3.2**2 , 3.2, 1]])

B = np.array([[6.85],
              [7.25],
              [6.42],
              [5.12]])

# PROCEDIMIENTO
casicero = 1e-15 # 0
AB = np.concatenate((A,B),axis=1)
tamano = np.shape(AB)
n = tamano[0]
m = tamano[1]

print('matriz aumentada: ')
print(AB)
# Gauss elimina hacia adelante
# tarea: verificar términos cero
for i in range(0,n,1):
    pivote = AB[i,i]
    adelante = i+1 
    for k in range(adelante,n,1):
        if (np.abs(pivote)>=casicero):
            factor = AB[k,i]/pivote
            AB[k,:] = AB[k,:] - factor*AB[i,:]
    print('Elimina hacia adelante')
    print(AB)

# Gauss-Jordan elimina hacia atras
ultfila = n-1
ultcolumna = m-1
for i in range(ultfila,0-1,-1):
    # Normaliza a 1 elemento diagonal
    AB[i,:] = AB[i,:]/AB[i,i]
    pivote = AB[i,i] # uno
    # arriba de la fila i
    atras = i-1 
    for k in range(atras,0-1,-1):
        if (np.abs(AB[k,i])>=casicero):
            factor = pivote/AB[k,i]
            AB[k,:] = AB[k,:]*factor - AB[i,:]
        else:
            factor= 'division para cero'
print('Elimina hacia atras')
print(AB)

X = AB[:,ultcolumna]

# Verifica resultado
verifica = np.dot(A,X)

# SALIDA
print('el vector solución X es:')
print(np.transpose([X]))

print('verificar que A.X = B')
print(np.transpose([verifica]))

# Revisa polinomio
a = np.min(puntos[:,0])
b = np.max(puntos[:,0])
muestras = 51

px = lambda x: X[0]*x**3 + X[1]*x**2 +X[2]*x + X[3]
xi = np.linspace(a,b,muestras)
pxi = px(xi)

# gráfica
plt.plot(xi,pxi)
plt.plot(puntos[:,0],puntos[:,1],'ro')
plt.show()