s1Eva_IT2018_T4 El gol imposible

Ejercicio: 1Eva_IT2018_T4 El gol imposible

Tabla de datos:

ti = [0.00, 0.15, 0.30, 0.45, 0.60, 0.75, 0.90, 1.05, 1.20]
xi = [0.00, 0.50, 1.00, 1.50, 1.80, 2.00, 1.90, 1.10, 0.30]
yi = [0.00, 4.44, 8.88,13.31,17.75,22.19,26.63,31.06,35.50]
zi = [0.00, 0.81, 1.40, 1.77, 1.91, 1.84, 1.55, 1.03, 0.30]

Observe que, un gol simplificado con física básica es un tiro parabólico cuya trayectoria se compone de movimientos en los ejes, Y y Z. Sin embargo, lo «imposible» del gol mostrado es añadir el movimiento en X. (Referencia de la imagen en el enunciado)

El movimiento de «profundidad» o dirección hacia el arco y(t) es semejante a un polinomio de primer grado, y el movimiento de «altura» z(t) es un polinomio de segundo grado. El movimiento «imposible» en el eje X, podría ser descrito por un polinomio de segundo o mayor grado.

a) Encontrar t para altura máxima, que se encuentra al igualar la derivada dz/dt a cero. Para interpolar el polinomio z(t), de segundo grado, se puede usar tres puntos de los sugeridos: 0, 0.3 y 0.6, que además son equidistantes en t (facilita usar cualquier método de interpolación).

Por ejemplo, con diferencias finitas avanzadas:

t z(t) d1 d2 d3
0.00 0.00 1.40 -0.89
0.30 1.40 0.51
0.60 1.91
z(t) = 0 + 1.40\frac{(t-0)}{1!(0.3)} - 0.89 \frac{(t-0)(t-0.3)}{2!(0.3)^2} = 0 + 4.66 t - 4.94(t^2-0.3t) = 4.66 t + 1.48 t - 4.94 t^2 z(t) = 6.42 t - 4.94 t^2

para encontrar el valor máximo se encuentra \frac{dz}{dt} = 0

\frac{dz}{dt} = 6.42 - 2(4.94) t 6.42 - 2(4.94) t = 0 t = \frac{6.42}{2(4.94)} t = 0.649

Observe que el resultado tiene sentido, pues según la tabla, el máximo debería estar entre 0.60 y 0.75

b) El cruce por la «barrera», corresponde al desplazamiento del balón en el eje Y a 9 metros: y(t) = 9.
El polinomio modelo de primer grado usa dos puntos para la interpolación, de los sugeridos se escogen dos, por ejemplo: 0.0 y 0.3.

Usando diferencias finitas avanzadas :

d1 = (8.88-0) = 8.88 y(t) = 0 + 8.88\frac{(t-0)}{1!(0.3)} y(t) = 29.6 t

usando y(t) = 9

29.6 t = 9
t = 0.30
z(0.30) = 1.40
(de la tabla de datos)

cuya respuesta con solo dos dígitos decimales es coherente, al estar cercano el valor a una distancia y=8.88 o aproximado a 9.
La respuesta puede ser mejorada usando más digitos significativos en las operaciones.

c)  La desviación máxima en eje X.
Determine un polinomio para la trayectoria en el eje X y obtenga el máximo igualando la derivada del polinomio x(t) a cero.

Por simplicidad, se usa un polinomio de segundo grado, alrededor de los valores máximos en el eje X

t x(t) d1 d2 d3
0.60 1.80 0.20 -0.30
0.75 2.00 -0.10
0.90 1.90
x(t) = 1.80 + 0.20 \frac{(t-0.60)}{1!(0.15)} -0.30 \frac{(t-0.60)(t-0.75)}{2!(0.15)^2} x(t) = 1.80 + 1.33 (t-0.60) - 6.67(t-0.60)(t-0.75)

como se busca el máximo, se usa la derivada \frac{dx}{dt} = 0

\frac{dx}{dt} = 1.33 - 6.67(2t +(-0.60-0.75)) 1.33 - 13.34t + 9.00 = 0 -13.34t + 10.33 = 0

t = 0.77

x(0.77) = 1.80 + 1.33(0.77-0.60) - 6.67(0.77-0.60)(0.77-0.75) x(0.77) = 2.003

lo que es coherente con la tabla para el eje x, pues el máximo registrado es 2, y el próximo valor es menor, la curva será decreciente.


Desarrollo extra para observar y verificar resultados:

Usando los puntos y un graficador 3D se puede observar la trayectoria:

Tarea: Realice el ejercicio usando los algoritmos en Python, muestre los polinomios obtenidos y compare.

Nota: La gráfica 3D presentada usa interpolación de Lagrange con todos los puntos. Realice las observaciones y recomendaciones necesarias y presente su propuesta como tarea.

s1Eva_IIT2017_T1 Aproximar a polinomio usando puntos

Ejercicio: 1Eva_IIT2017_T1 Aproximar a polinomio usando puntos

Se dispone de tres puntos para la gráfica.

x  f(x)
 0  1
 0.2  1.6
 0.4  2.0

Si el polinomio de Taylor fuera de grado 0, sería una constante, que si se evalua en x0 = 0 para eliminar los otros términos, se encuentra que sería igual a 1

Como se pide el polinomio de grado 2, se tiene la forma:

p(x) = a + bx + c x 2

p(x) = 1 + bx + c x 2

Se disponen de dos puntos adicionales que se pueden usar para determinar b y c:

p(0.2) = 1 + 0.2 b + (0.2)2 c = 1.6
p(0.4) = 1 + 0.4 b + (0.4)2 c = 2.0
simplificando:
0.2 b + (0.2)2 c = 1.6 - 1 = 0.6
0.4 b + (0.4)2 c = 2.0 - 1 = 1

multiplicando la primera ecuación de 2 y restandole la segunda ecuación:

// - 0.08 c =  1.2-1 = 0.2
c = - 0.2/0.08 = -2.5

0.2 b + 0.04(-2.5) = 0.6
0.2 b = 0.6 + 0.04*2.5 = 0.6 + 0.1 = 0.7
    b =  0.7/0.2 =  3.5

con lo que el polinomio queda:
p(x) = 1 + 3.5 x – 2.5 x2

validando con python:
tomando los puntos de prueba:

[ 0.   0.2  0.4]
[ 1.   1.6  2. ]
>>>

se obtiene la gráfica:

se adjunta las instrucciones usadas para validar

import numpy as np
import matplotlib.pyplot as plt

xi = np.linspace(-0.5,1,51)
px = lambda x: 1+ 3.5*x - 2.5*(x**2)
pxi = px(xi)
prueba = np.array([0,0.2,0.4])
puntos = px(prueba)

# Salida
print(prueba)
print(puntos)

# Gráfica
plt.plot(xi,pxi)
plt.plot(prueba,puntos,'*')
plt.show()

Nota: Se puede intentar realizar los polinomios aumentando el grado, sin embargo cada término agrega un componente adicional a los términos anteriores por la forma (x – x0)k

s1Eva_IT2017_T4 Componentes eléctricos

Ejercicio: 1Eva_IT2017_T4 Componentes eléctricos

Desarrollo Analítico

Solo puede usar las cantidades disponibles de material indicadas, por lo que las cantidades desconocidas de produccion por componente se convieren en las incógnitas x0, x1, x2. Se usa el índice cero por compatibilidad con las instrucciones python.

Material 1 Material 2 Material 3
Componente 1 5 x0 9 x0 3 x0
Componente 2 7 x1 7 x1 16 x1
Componente 3 9 x2 3 x2 4 x2
Total 945 987 1049

Se plantean las fórmulas a resolver:

5 x0 +  7 x1 + 9 x2 = 945
9 x0 +  7 x1 + 3 x2 = 987
3 x0 + 16 x1 + 4 x2 = 1049

Se reescriben en la forma matricial AX=B

\begin{bmatrix} 5 & 7 & 9\\ 9 & 7 & 3 \\ 3& 16 & 4\end{bmatrix} \begin{bmatrix} x_0 \\ x_1 \\ x_2 \end{bmatrix}= \begin{bmatrix} 945 \\ 987 \\ 1049 \end{bmatrix}

Se reordena, pivoteando por filas para tener la matriz diagonalmente dominante:

\begin{bmatrix} 9 & 7 & 3\\ 3 & 16 & 4 \\ 5& 7 & 9\end{bmatrix} \begin{bmatrix} x_0 \\ x_1 \\ x_2 \end{bmatrix}= \begin{bmatrix} 987 \\ 1049 \\ 945 \end{bmatrix}

Se determina el número de condición de la matriz. Por facilidad con python:

numero de condicion: 4.396316324708121

Obtenido con:

# 1Eva_IT2017_T4 Componentes eléctricos
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
A = np.array([[9., 7.,3.],
              [3.,16.,4.],
              [5., 7.,9.]])

B = np.array([987.,1049.,945.])
# PROCEDIMIENTO

# numero de condicion
ncond = np.linalg.cond(A)

# SALIDA
print('numero de condicion:', ncond)

Recordando que la matriz debe ser tipo real, se añade un punto a los dígitos.

El número de condición es cercano a 1, por lo que el sistema si debería converger a la solución.

Desarrollo con Python

La forma AX=B permite usar los algoritmos desarrollados, obteniendo la solución. Se verifica el resultado al realizar la multiplicación de A con el vector respuesta, debe ser el vector B con un error menor al tolerado.

respuesta con Jacobi
[[62.99996585]
 [44.99998037]
 [34.9999594 ]]
verificando:
[[ 986.99943346]
 [1048.99942111]
 [ 944.99932646]]

Si interpreta el resultado, se debe obtener solo la parte entera [63,45,35] pues las unidades producidas son números enteros.

instrucciones:

# 1Eva_IT2017_T4 Componentes eléctricos
import numpy as np

def jacobi(A,B,tolera,X,iteramax=100):
    tamano = np.shape(A)
    n = tamano[0]
    m = tamano[1]
    diferencia = np.ones(n, dtype=float)
    errado = np.max(diferencia)
    xnuevo = np.copy(X)

    itera = 0
    print(itera, X)
    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)
        print(itera, xnuevo)
        X = np.copy(xnuevo)
        itera = itera + 1
    # Vector en columna
    X = np.transpose([X])
    # No converge
    if (itera>iteramax):
        X=itera
    return(X)


# INGRESO
A = np.array([[9., 7.,3.],
              [3.,16.,4.],
              [5., 7.,9.]])

B = np.array([987.,1049.,945.])
tolera = 1e-4

X = [0.,0.,0.]

# PROCEDIMIENTO

# numero de condicion
ncond = np.linalg.cond(A)

respuesta = jacobi(A,B,tolera,X)

verifica = np.dot(A,respuesta)

# SALIDA
print('numero de condicion:', ncond)
print('respuesta con Jacobi')
print(respuesta)
print('verificando:')
print(verifica)

al ejecutar el algoritmo se determina que se requieren 83 iteraciones para cumplir con con el valor de error tolerado.

s1Eva_IT2017_T2 Tanque esférico-volumen

Ejercicio: 1Eva_IT2017_T2 Tanque esférico-volumen

a. Planteamiento del problema

V = \frac{\pi h^{2} (3r-h)}{3}

Si r=1 m y V=0.75 m3,

0.75 = \frac{\pi h^{2} (3(1)-h)}{3} 0.75 -\frac{\pi h^{2} (3(1)-h)}{3} = 0 f(h) = 0.75 -\frac{\pi h^{2} (3-h)}{3} = 0.75 -\frac{\pi}{3}(h^{2} (3)-h^{2}h) = 0.75 -\frac{\pi}{3}(3 h^{2} - h^{3}) f(h) = 0.75 -\pi h^{2} + \frac{\pi}{3}h^{3}

b. Intervalo de búsqueda de raíz

El tanque vacio tiene h=0 y completamente lleno h= 2r = 2(1) = 2, por lo que el intevalo tiene como extremos:

[0,2]

Verificando que exista cambio de signo en la función:

f(0) = 0.75 -\pi (0)^{2} + \frac{\pi}{3}(0)^{3} = 0.75 f(2) = 0.75 -\pi (2)^{2} + \frac{\pi}{3}(2)^{3}= -3.4387

y verificando al usar la gráfica dentro del intervalo:

Tolerancia

Se indica en el enunciado como 0.01 que es la medición mínima a observar con un flexómetro.

tolera = 0.01


c. Método de Newton-Raphson
d. Método de Punto Fijo


c. Método de Newton-Raphson

El método de Newton-Raphson requiere la derivada de la función:

x_{i+1} = x_i -\frac{f(x_i)}{f'(x_i)} f(h) = 0.75 -\pi h^{2} + \frac{\pi}{3}h^{3} f'(h) = -2\pi h + \pi h^{2}

Tomando como punto inicial de búsqueda el extremo izquierdo del intervalo, genera una división para cero. Por lo que se mueve un poco a la derecha, algo más cercano a la raiz, viendo la gráfica por ejemplo 0.1

x0 = 0.1

iteración 1

i =0

f(0.1) = 0.75 -\pi (0.1)^{2} + \frac{\pi}{3}(0.1)^{3} =0.7196 f'(0.1) = -2\pi (0.1) + \pi (0.1)^{2} = -0.5969 x_{1} = x_0 -\frac{0.7496 }{-0.0625} = 1.3056 tramo = |x_{1}-x_{0}| = |0.1-1.3056 | = 1.2056

iteración 2

i =1

f(1.3056) = 0.75 -\pi (1.3056)^{2} + \frac{\pi}{3}(1.3056)^{3} = -2.2746 f'(1.3056) = -2\pi (1.3056) + \pi (1.3056)^{2} =-2.8481 x_{1} = x_0 -\frac{-2.2746}{-2.8481} = 0.5069 tramo = |x_{2}-x_{1}|=|0.5069-1.3056|=0.7987

iteración 3

i =2

f(0.5069) = 0.75 -\pi (0.5069)^{2} + \frac{\pi}{3}(0.5069)^{3} = 0.0789 f'(0.5069) = -2\pi (0.5069) + \pi (0.5069)^{2} =-2.3780 x_{1} = x_0 -\frac{0.0789}{-2.3780} = 0.5401 tramo = |x_{3}-x_{2}| =|0.5401 - 0.5069| = 0.0332

Observe que el tramo disminuye en cada iteración , por lo que el método converge, si se siguen haciendo las operaciones se tiene que:

 [ xi, xnuevo, tramo]
[[1.00000000e-01 1.30560920e+00 1.20560920e+00]
 [1.30560920e+00 5.06991599e-01 7.98617601e-01]
 [5.06991599e-01 5.40192334e-01 3.32007350e-02]
 [5.40192334e-01 5.39518667e-01 6.73667593e-04]]
raiz 0.5395186666699257

Instrucciones en Python

para Método de Newton-Raphson

# 1Eva_IT2017_T2 Tanque esférico-volumen
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
fx = lambda h: 0.75 - np.pi*(h**2)+(np.pi/3)*h**3
dfx = lambda h: -2*np.pi*h+np.pi*(h**2)

# Parámetros de método
a = 0
b = 2
tolera = 0.01
x0 = 0.1
iteramax = 100

# parametros de gráfica
La = a
Lb = b
muestras = 21

# PROCEDIMIENTO
# Newton-Raphson
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
tabla = np.array(tabla)

# calcula para grafica
hi = np.linspace(La,Lb,muestras)
fi = fx(hi)
gi = dfx(hi)

# SALIDA
print(' [ xi, xnuevo, tramo]')
print(tabla)
print('raiz', xnuevo)
plt.plot(hi,fi)
plt.plot(xi,fx(xi),'ro')
plt.axhline(0, color='green')
plt.xlabel('h')
plt.ylabel('V')
plt.title('Método Newton-Raphson')
plt.show()

Planteo con Punto Fijo


d. Método de Punto Fijo

Del planteamiento del problema en el literal a, se tiene que:

0.75 = \frac{\pi h^{2} (3(1)-h)}{3}

de donde se despeja una h:

\frac{3(0.75)}{\pi (3(1)-h) } = h^{2} h = \sqrt{\frac{3*0.75}{\pi (3-h) }} h = \sqrt{\frac{2.25}{\pi (3-h) }}

con lo que se obtienen las expresiones a usar en el método

identidad = h g(h) = \sqrt{\frac{2.25}{\pi (3-h) }}

El punto inicial de búsqueda debe encontrarse en el intervalo, se toma el mismo valor que x0 en el método de Newton-Raphson

x0 = 0.10

Iteracion 1

x_0= 0.10 g(0.10) = \sqrt{\frac{2.25}{\pi (3-(0.10) }}= 0.4969 tramo= |0.4969-0.10| = 0.3869

Iteracion 2

x_1= 0.4969 g(0.4969) = \sqrt{\frac{2.25}{\pi (3-(0.4969 ) }}= 0.5349 tramo= |0.5349- 0.4969| = 0.038

Iteracion 3

x_2 =0.5349 g(0.5349) = \sqrt{\frac{2.25}{\pi (3-(0.5349) }}= 0.5390 tramo= |0.5390 - 0.5349| = 0.0041

con lo que se cumple el criterio de tolerancia, y se obtiene la raiz de:

raiz = 0.5390

Tabla de resultados, donde se observa que el tramo o error en cada iteración disminuye, por lo que el método converge.

 [i,xi,xi+1,tramo]
[[1.         0.1        0.4969553  0.3969553 ]
 [2.         0.4969553  0.5349116  0.03795631]
 [3.         0.5349116  0.53901404 0.00410243]]
raiz 0.5390140355891347
>>> 

Instrucciones en Python

para Método de Punto-Fijo, recordamos que el método puede diverger, por lo que se añade el parámetro iteramax

# 1Eva_IT2017_T2 Tanque esférico-volumen
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
fx = lambda h: h
gx = lambda h: np.sqrt(2.25/(np.pi*(3-h)))

a = 0.1
b = 2
tolera = 0.01
iteramax = 100

La = a
Lb = b
muestras = 21

# PROCEDIMIENTO
# Punto Fijo
tabla = []
i = 1 # iteración
b = gx(a)
tramo = abs(b-a)
while not(tramo<=tolera or i>=iteramax):
    tabla.append([i,a,b,tramo])
    a = b
    b = gx(a)
    tramo = abs(b-a)
    i = i+1
tabla.append([i,a,b,tramo])
respuesta = b

# Validar respuesta
if (i>=iteramax):
    respuesta = np.nan
tabla = np.array(tabla)

# calcula para grafica
hi = np.linspace(La,Lb,muestras)
fi = fx(hi)
gi = gx(hi)

# SALIDA
print(' [i, xi, xi+1, tramo]')
print(tabla)
print('raiz', respuesta)
plt.plot(hi,fi, label = 'identidad', color='green')
plt.plot(hi,gi, label = 'g(h)', color = 'orange')
plt.plot(b,gx(b),'ro')
plt.axhline(0, color='green')
plt.xlabel('h')
plt.ylabel('V')
plt.title('Método Punto Fijo')
plt.legend()
plt.axhline(0, color='green')
plt.show()

Otra forma de probar la convergencia es que |g'(x)|<1 que se observa en la una gráfica adicional, lo que limita aún más el intervalo de búsqueda.

Desarrollo en la siguiente clase.


s1Eva_IT2016_T3_MN Tasa interés anual

Ejercicio: 1Eva_IT2016_T3_MN Tasa interés anual

Propuesta de Solución  empieza con el planteamiento del problema, luego se desarrolla con el método de Bisección y método del Punto Fijo solo con el objetivo de comparar resultados.


Planteamiento del problema

La fórmula del enunciado para el problema es:

A = P \frac{i(1+i)^{n}}{(1+i)^{n} -1}

que con los datos dados se convierte a:

5800 = 35000 \frac{i(1+i)^8}{(1+i)^8 -1} 35000 \frac{i(1+i)^8}{(1+i)^8 -1}-5800 =0

que es la forma de f(x) = 0

f(i)=35000 \frac{i(1+i)^8}{(1+i)^8 -1}-5800

Intervalo de búsqueda

Como el problema plantea la búsqueda de una tasa de interés, consideramos que:

  • Las tasas de interés no son negativas. ⌉(i<0)
  • Las tasas de interés no son cero en las instituciones bancarias (i≠0)
  • Las tasas muy grandes 1 = 100/100 = 100% tampoco tienen mucho sentido

permite acotar la búsqueda a un intervalo (0,1].
Sin embargo tasas demasiado altas tampoco se consideran en el problema pues el asunto es regulado (superintendencia de bancos), por lo que se podría intentar entre un 1% = 0.01l y la mitad del intervalo 50%= 0.5 quedando

[0.01,0.5]

Tolerancia

si la tolerancia es de tan solo menor a un orden de magnitud que el valor buscado, se tiene que las tasas de interés se representan por dos dígitos después del punto decimal, por lo que la tolerancia debe ser menor a eso.

Por ejemplo: tolerancia < 0.001 o aumentando la precisión

tolera = 0.0001


Método de la Bisección

itera = 1

a = 0.01, b = 0.5

c = \frac{a+b}{2} = \frac{0.01+0.5}{2} = 0.255 f(0.01) = 35000 \frac{0.01(1+0.01)^8}{(1+0.01)^8-1}-5800 = -1225.83 f(0.5) = 35000 \frac{0.5(1+0.5i)^8}{(1+0.5)^8-1}-5800 = 12410.54

con lo que se verifica que existe cambio de signo al evaluar f(x) en el intervalo y puede existir una raíz.

f(0.255) = 35000 \frac{0.255(1+0.255)^8}{(1+0.255)^8-1}-5800 = 4856.70

lo que muestra que f(x) tiene signos en a,c,b de (-) (+) (+), seleccionamos el intervalo izquierdo para continuar la búsqueda [0.01, 0.255]

El tramo permite estimar el error, reduce el intervalo a:

tramo = b-a = 0.255-0.01 = 0.245

valor que todavía es más grande que la tolerancia de 10-4, por lo que hay que continuar las iteraciones.

itera = 2

a = 0.01, b = 0.255

c = \frac{0.01+0.255}{2} = 0.1325 f(0.01) = -1225.83 f(0.255) = 4856.70 f(0.1325 ) = 35000 \frac{0.1325(1+0.1325)^8}{(1+0.1325)^8-1}-5800 = 1556.06

lo que muestra que f(x) tiene signos en a,c,b de (-) (+) (+), seleccionamos el intervalo izquierdo para continuar la búsqueda [0.01, 0.1325]

El tramo permite estimar el error, reduce el intervalo a:

tramo = b-a = 0.1325-0.01 = 0.1225

valor que todavía es más grande que la tolerancia de 10-4, por lo que hay que continuar las iteraciones.

itera = 3

a = 0.01, b = 0.1325

c = \frac{0.01+0.1225}{2} = 0.071 f(0.01) = -1225.83 f(0.1325) = 1556.06 f(0.071 ) = 35000 \frac{0.071(1+0.071)^8}{(1+0.071)^8-1}-5800 = 89.79

lo que muestra que f(x) tiene signos en a,c,b de (-) (+) (+), seleccionamos el intervalo izquierdo para continuar la búsqueda [0.01, 0.071]

El tramo permite estimar el error, reduce el intervalo a:

tramo = b-a = 0.071-0.01 = 0.061

valor que todavía es más grande que la tolerancia de 10-4, por lo que hay que continuar las iteraciones.

Para una evaluación del tema en forma escrita es suficiente para mostrar el objetivo de aprendizaje, el valor final se lo encuentra usando el algoritmo.

       raiz en:  0.06724243164062502
error en tramo:  5.981445312500111e-05
iteraciones:  13
>>>

Algoritmo en Python

# 1Eva_IT2016_T3_MN Tasa interés anual
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
fx = lambda x: 35000*(x*(1+x)**8)/((1+x)**8 -1) -5800
a = 0.01
b = 0.5
tolera = 0.0001

# PROCEDIMIENTO
cuenta = 0
np.set_printoptions(precision=3)
tramo = b-a
while not(tramo<tolera):
    c = (a+b)/2
    fa = fx(a)
    fb = fx(b)
    fc = fx(c)
    cambia = np.sign(fa)*np.sign(fc)
    if cambia < 0: a = a b = c if cambia > 0:
        a = c
        b = b
    tramo = b-a
    cuenta = cuenta+1

# SALIDA
print('       raiz en: ', c)
print('error en tramo: ', tramo)
print('iteraciones: ',cuenta)


Método del Punto Fijo

El planteamiendo del punto fijo se realiza con x= g(x), por lo que se reordena la ecuación a:

35000 \frac{i(1+i)^8}{(1+i)^8 -1}-5800 =0 35000 \frac{i(1+i)^8}{(1+i)^8 -1}=5800 \frac{i(1+i)^8}{(1+i)^8 -1}=\frac{5800}{35000} i=\frac{58}{350} \frac{(1+i)^8 -1} {i(1+i)^8}

con lo que g(x) es:

g(i)=\frac{58}{350} \frac{(1+i)^8 -1} {(1+i)^8}

valor inicial de búsqueda

Para el punto inicial i0 se puede usar uno de los extremos del intervalo propuesto en la sección de planteamiento. Para reducir aun más la búsqueda se pude seleccionar el punto intermedio

 i0 = 0.255

Itera = 1

 i0 = 0.255

g(0.255i)=\frac{58}{350} \frac{(1+0.255)^8 -1} {(1+0.255)^8} = 0.1387

el error se estrima como el tramo recorrido entre el valor nuevo y el valor inicial

tramo = | nuevo-antes| = |0.1387 - 0.255| = 0.1163

como el tramo o error es aún mayor que el valor de tolera, se continúa con la siguiente iteración.

Itera = 2

i1 = g(i0 ) = 0.1387

g(0.1387)=\frac{58}{350} \frac{(1+0.1387)^8 -1} {(1+0.1387)^8} = 0.1071

el error se estrima como el tramo recorrido entre el valor nuevo y el valor inicial

tramo = | nuevo-antes| = |0.1071 - 0.1387| = 0,0316

como el tramo o error es aún mayor que el valor de tolera, se continúa con la siguiente iteración.

Itera = 3

i2 = g(i1 ) = 0.1071

g(0.1071)=\frac{58}{350} \frac{(1+0.1071)^8 -1} {(1+0.1071)^8} = 0.0922

el error se estrima como el tramo recorrido entre el valor nuevo y el valor inicial

tramo = | nuevo-antes| = |0.0922 - 0.1071| = 0,0149

como el tramo o error es aún mayor que el valor de tolera, se continúa con la siguiente iteración.

Observación: Como el error disminuye entre cada iteración, se considera que el método converge, si se realizan suficientes iteraciones se cumplierá con el valor de tolerancia y se habrá llegado a la precisión requerida.

Usando el algoritmo se tiene:

iteraciones: 17
    raiz en: 0.06754389199556779
>>>

Algoritmo en Python

# Algoritmo de Punto Fijo
# x0 valor inicial de búsqueda
# error = tolera

import numpy as np
def puntofijo(gx,antes,tolera, iteramax=50):
    itera = 1 # iteración
    nuevo = gx(antes)
    tramo = abs(nuevo-antes)
    while(tramo>=tolera and itera<=iteramax ):
        antes = nuevo
        nuevo = gx(antes)
        tramo = abs(nuevo-antes)
        itera = itera+1
    respuesta = nuevo
    # Validar respuesta
    if (itera>=iteramax ):
        respuesta = np.nan
    print('iteraciones:',itera)
    return(respuesta)

# PROGRAMA ---------

# INGRESO
gx = lambda i: (58/350)*((1+i)**8-1)/((1+i)**8)

a = 0       # intervalo
b = 0.5

x0 = 0.255
tolera = 0.0001
iteramax  = 50      # itera máximo

# PROCEDIMIENTO
respuesta = puntofijo(gx,0.255,tolera,iteramax)

# SALIDA
print('    raiz en:',respuesta)

s1Eva_IT2015_T4 Lingotes metales

Ejercicio: 1Eva_IT2015_T4 Lingotes metales

Se plantea que cada lingote debe aportar una proporción xi al lingote nuevo a ser fundido.

Se dispone de los compuestos de cada lingote por filas:

compuesto = np.array([[ 20, 50, 20, 10],
                      [ 30, 40, 10, 20],
                      [ 20, 40, 10, 30],
                      [ 50, 20, 20, 10]])
proporcion = np.array([ 27, 39.5, 14, 19.5])

El contenido final de cada componente basado en los aportes xi de cada lingote para cada componente.

Ejemplo para los 27 gramos de oro

20x_1 + 30x_2+ 20x_3 + 50x_4 = 27

se realiza el mismo procedimiento para los otros tipos de metal.

50x_1 + 40x_2+ 40x_3 + 20x_4 = 39.5 20x_1 + 10x_2+ 10x_3 + 20x_4 = 14 10x_1 + 20x_2+ 30x_3 + 10x_4 = 19.5

Las ecuaciones se escriben en la forma matricial Ax=B

\begin{bmatrix} 20 && 30&& 20 &&50 \\ 50 && 40 && 40 && 20 \\ 20 && 10 && 10 && 20 \\ 10 && 20 && 30 && 10 \end{bmatrix} = \begin{bmatrix} x_1 \\ x_2 \\x_3 \\ x_4 \end{bmatrix} = \begin{bmatrix} 27 \\ 39.5 \\ 14 \\ 19.5 \end{bmatrix}

Para resolver se plantea la matriz aumentada

\begin{bmatrix} 20 && 30&& 20 &&50 && 27\\ 50 && 40 && 40 && 20 && 39.5\\ 20 && 10 && 10 && 20 && 14 \\ 10 && 20 && 30 && 10 && 19.5 \end{bmatrix}

se pivotea por filas la matriz:

\begin{bmatrix} 50 && 40 && 40 && 20 && 39.5\\ 20 && 30&& 20 &&50 && 27\\ 10 && 20 && 30 && 10 && 19.5 \\ 20 && 10 && 10 && 20 && 14 \end{bmatrix}

Para eliminar hacia adelante:

\begin{bmatrix} 50 && 40 && 40 && 20 && 39.5 \\ 20 - 50\frac{20}{50} && 30-40\frac{20}{50} && 20-40\frac{20}{50} && 50-20\frac{20}{50} && 27-39.5\frac{20}{50}\\ 10 - 50\frac{10}{50} && 20-40\frac{10}{50} && 30-40\frac{10}{50} && 10-20\frac{10}{50} && 19.5-39.5\frac{10}{50} \\ 20 - 50\frac{20}{50} && 10-40\frac{20}{50} && 10-40\frac{20}{50} && 20-20\frac{20}{50} && 14-39.5\frac{20}{50} \end{bmatrix}

continuando con el desarrollo:

Elimina hacia adelante
[[50.  40.  40.  20.  39.5]
 [ 0.  14.   4.  42.  11.2]
 [ 0.  12.  22.   6.  11.6]
 [ 0.  -6.  -6.  12.  -1.8]]
Elimina hacia adelante
[[ 50.  40.  40.      20.  39.5]
 [  0.  14.   4.      42.  11.2]
 [  0.   0.  18.5714 -30.   2. ]
 [  0.   0.  -4.2857  30.   3. ]]
Elimina hacia adelante
[[ 50.  40.  40.      20.     39.5   ]
 [  0.  14.   4.      42.     11.2   ]
 [  0.   0.  18.5714 -30.      2.    ]
 [  0.   0.   0.      23.0769  3.4615]]
Elimina hacia adelante
[[ 50.  40.   40.      20.     39.5  ]
 [  0.  14.    4.      42.     11.2  ]
 [  0.   0.   18.5714 -30.      2.   ]
 [  0.   0.    0.      23.0769  3.4615]]
Elimina hacia atras
[[ 1.    0.    0.    0.    0.25]
 [ 0.    1.    0.    0.    0.25]
 [ 0.    0.    1.   -0.    0.35]
 [ 0.    0.    0.    1.    0.15]]
el vector solución X es:
[[0.25]
 [0.25]
 [0.35]
 [0.15]]
verificar que A.X = B
[[39.5]
 [27. ]
 [19.5]
 [14. ]]

Las proporciones de cada lingote a usar para el nuevo lingote que cumple con lo solicitado son:

[0.25, 0.25, 0.35, 0.15]


Algoritmo en python

usado para la solución es:

# 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
A = np.array([[ 50., 40, 40, 20],
              [ 20., 30, 20, 50],
              [ 10., 20, 30, 10],
              [ 20., 10, 10, 20]])
B1 = np.array([ 39.5, 27, 19.5, 14])

B = np.transpose([B1])

# 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]))

Tarea: Revisar sobre la última pregunta.

s1Eva_IT2015_T2 Salida cardiaca

Ejercicio: 1Eva_IT2015_T2 Salida cardiaca

Solución presentada como introducción al tema de interpolación y solución de sistemas de ecuaciones.
No realiza el literal c, no se desarrolla el tema de integrales.

Note que el desarrollo del tema permite aumentar el grado del polinomio de interpolación, lo que se afecta al tamaño del sistema de ecuaciones (matriz).

Los valores obtenidos con la solución propuesta son:

solución para X por Gauss-Seidel
[[-0.42175867]
 [ 0.15610893]
 [ 0.02736763]]
verifica que A.X = B:
[[ -7.02831455e-05]
 [  1.50012970e+00]
 [  3.20000000e+00]]
polinomio interpolación, con puntos:  3
0.0273676337623498*x**2 + 0.156108926206362*x - 0.421758670607596
>>>

La gráfica para observar los datos experimentales es:

La gráfica con polinomio de interpolación de grado 2, con tres puntos:

instrucciones del problema para la solución por partes en python:

# 1ra Evaluación I Término 2015
# Tema 2. Flujo de sangre en corazón
# Tarea: parte c), no se ha realizado el áre bajo curva
#        falta calcular salida cardiaca.
import numpy as np
import matplotlib.pyplot as plt

# Gráfica de datos experimentales:
t = np.array([2,6,9,12,15,18])
y = np.array([0,1.5,3.2,4.1,3.4,2.0])

# SALIDA
plt.plot(t,y)
plt.title('datos del experimento: t vs concentración ')
plt.show()

# Sistema de ecuaciones para aproximar a polinomio grado 2
# para grado dos usa tres puntos,
# por ejemplo usando el punto [ 2, 0] del experimento
# a + b*(2) + c*(2**2) =  0
A = np.array([[1,2,2**2],
              [1,6,6**2],
              [1,9,9**2]])
B = np.array([[0],
              [1.5],
              [3.2]])

tolera = 0.0001
X = np.zeros(len(B), dtype = float)

# usando numpy para solucion de matrices
# Xnp = np.linalg.solve(A,B)
# print('solución para A.X=B con numpy')
# print(Xnp)

# algoritmo Gauss-Seidel
iteramax=100
tamano = np.shape(A)
n = tamano[0]
m = tamano[1]
diferencia = np.ones(n, dtype=float)
errado = np.max(diferencia)

itera = 0
while (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]
        diferencia[i] = np.abs(nuevo-X[i])
        X[i] = nuevo
    errado = np.max(diferencia)
    itera = itera + 1
# Vector en columna
X =  np.transpose([X])
# No converge
if (itera>iteramax):
    X=0

Xgs = X

# Metodo numérico Gauss_Seidel
verifica = np.dot(A,Xgs)
print('solución para X por Gauss-Seidel')
print(Xgs)

# verificar resultado
print('verifica que A.X = B: ')
print(verifica)

# Observar interpolacion con polinomio creado
pt = lambda t: Xgs[0,0]+ Xgs[1,0]*t + Xgs[2,0]*t**2

ti = np.linspace(2,18,501)
pti = pt(ti)

plt.plot(ti,pti, label = 'interpolacion')
plt.plot(t,y,'*', label = 'datos experimento')
plt.title('interpolación con polinomio')
plt.legend()
plt.show()

# polinomio en sympy
import sympy as sp
x = sp.Symbol('x')
polinomio = 0
k = len(Xgs)
for i in range(0,k,1):
    polinomio = polinomio + Xgs[i,0]*x**i
print('polinomio interpolación, con puntos: ', k) 
print(polinomio)

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

1.1 Solución iterativa usando el médodo 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_0 \\ x_1 \\ x_2 \end{bmatrix} = \begin{bmatrix} 1 \\ 6 \\ -26 \end{bmatrix}

para usarla en el algoritmo se intercambian filas, pivoteo, buscando hacerla diagonal dominante:

\begin{bmatrix} 7 & 1 & 1 \\ -3 & 7 &-1\\ -2 & 5 & 9 \end{bmatrix} \begin{bmatrix} x_0 \\ x_1 \\ x_2 \end{bmatrix} = \begin{bmatrix} 6 \\ -26 \\1 \end{bmatrix}

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

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

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

Nota. El super índice entre paréntesis denota el número de la iteración. El subíndice denota el elemento del vector. 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…

Iteración 1

\begin{cases}x=(6-(0)-(0))/(7)\\y=(-26+3(0)+(0))/(7)\\z=(1+2(0)-5(0))/(9)\end{cases}
X(1) = [6/7, -26/7, 1/9] 
    = [0.8571, -3,7142, 0.1111]
diferencia(1) = |X(1) - X(0)|
             = |[0.8571,-3,7142,0.1111] - [0,0,0]|
             = |[0.8571,-3,7142,0.1111]|
errado(1) = maximo|[0.8571,-3,7142,0.1111]|
         = 26/7 ≅ 3.71, 
error es más alto que lo tolerado

Iteración 2

\begin{cases}x=(6-(-26/7)-(1/9))/(7)\\y=(-26+3(6/7)+(1/9))/(7)\\z=(1+2(6/7)-5(-26/7))/(9)\end{cases}
X(2) = [1.3718, -3.3310 ,  2,3650]
diferencia(2) = |X(2) - X(1)|
             = |[1.3718, -3.3310 , 2,3650] - [0.8571, -3,7142, 0.1111]| 
             = |[0.5146, 0.3832, 2.2539]|
errado(2) ≅ 2.2538, 
el error disminuye, pero es más alto que lo tolerado

Iteración 3

\begin{cases}x=(6-(-3.3310)-( 2,3650))/(7)\\y=(-26+3x+z)/(7)\\z=(1+2x-5y)/(9)\end{cases}
X(3) = [0.9951, -2.7884, 2.2665]
diferencia(3) = |[0.9951, -2.7884, 2.2665] - [1.3718, -3.3310 ,  2,3650]|
             = |[-0.3767, 0.5425, -0.0985]|
errado(3) ≅ 0.5425, 
el error disminuye, pero es más alto que lo tolerado

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:

Xi, errado
[ 0.85714286 -3.71428571  0.11111111] 3.71428571429
[ 1.37188209 -3.33106576  2.36507937] 2.25396825397
[ 0.99514091 -2.78846777  2.26656589] 0.542597991578
[ 0.93170027 -2.96400162  1.8814023 ] 0.385163589245
[ 1.0117999  -3.04621384  1.96482318] 0.0834208883016
[ 1.01162724 -2.99996816  2.02829656] 0.0634733731283
[ 0.99595309 -2.99097453  2.00256614] 0.0257304176216
[ 0.99834406 -3.0013678   1.99408654] 0.0103932672897
[ 1.00104018 -3.00155447  2.0003919 ] 0.00630536414945
[ 1.00016608 -2.99949822  2.00109475] 0.00205624814582
[ 0.99977193 -2.99977243  1.99975814] 0.00133660433338
[ 1.00000204 -3.0001323   1.99982289] 0.000359867509479
[ 1.0000442  -3.00002443  2.00007395] 0.000251063280064
[ 0.99999292 -2.99997049  2.00002339] 5.39347670632e-05
iteraciones:  13

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.

Tarea: convierta el algoritmo a una función, así es más sencillo usar en otros ejercicios.
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.

# 1ra Evaluación II Término 2011
# Tema 2. Sistema ecuaciones Jacobi
import numpy as np

# INGRESO
A = np.array([[ 7.0, 1, 1],
              [-3.0, 7,-1],
              [-2.0, 5, 9]])

B = np.array([6.0, -26.0, 1.0])

X = np.array([0.0, 0.0,  0.0],dtype=float)
tolera = 0.0001
iteramax = 100

# PROCEDIMIENTO
tamano = np.shape(A)
n = tamano[0]
m = tamano[1]
Xi1 = np.zeros(n, dtype=float)
errado = 2*tolera
itera = 0
while not(errado<=tolera or itera>=iteramax):
    i = 0
    while not(i>=n):
        j = 0
        nuevo = B [i]
        while not(j>=m):
            if (i!=j):
                nuevo = nuevo - A[i,j]*X[j]
            j = j+1
        Xi1[i] = nuevo/A[i,i]
        i = i+1
    diferencia = np.abs(X - Xi1)
    errado = np.max(diferencia)
    X = np.copy(Xi1)
    itera = itera +1
    print(Xi1, errado)

# SALIDA
print('iteraciones: ', itera-1)

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 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.