Autor Tema: Duda Python

0 Usuarios y 1 Visitante están viendo este tema.

12 Noviembre, 2021, 05:15 pm
Leído 864 veces

Beautyofmaths

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 100
  • País: es
  • Karma: +0/-0
Hola buenas, estoy intentando hacer un programa en Python para resolver el siguiente ejercicio:

"Crea una función que, dada una matriz cuadrada A, compruebe si es invertible o no; y en caso afirmativo, calcule la inversa de A mediante el método de los adjuntos."

La profesora nos aconsejó crear una función recursiva a partir del caso base de una matriz 2x2, pero no sé cómo hacerlo. Muchas gracias de antemano.

12 Noviembre, 2021, 06:37 pm
Respuesta #1

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 10,239
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Hola buenas, estoy intentando hacer un programa en Python para resolver el siguiente ejercicio:

"Crea una función que, dada una matriz cuadrada A, compruebe si es invertible o no; y en caso afirmativo, calcule la inversa de A mediante el método de los adjuntos."

La profesora nos aconsejó crear una función recursiva a partir del caso base de una matriz 2x2, pero no sé cómo hacerlo. Muchas gracias de antemano.

Puf, si me pongo, lo hago, pero a ojo me parece pesado de programar, así por encima; y estos días estoy recolectando leña, no se si mañana a lo largo del día, a ver. Si eso te digo. Con un poco de suerte pasará antes alguien.

Saludos.

12 Noviembre, 2021, 06:43 pm
Respuesta #2

Beautyofmaths

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 100
  • País: es
  • Karma: +0/-0
Aprecio tu ayuda. Sin embargo, creo que ya he conseguido, inspirado por algún programa similar que he visto en Internet, resolver el ejercicio. En cuanto llegue a mi casa adjunto el script. Sin embargo, ahora tengo dudas sobre cómo afrontar este otro ejercicio:

"Crea una función que, dados n + 1 puntos, devuelva el polinomio interpolador en términos de sus coeficientes".
De nuevo gracias. Saludos.

12 Noviembre, 2021, 06:55 pm
Respuesta #3

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 10,239
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Aprecio tu ayuda. Sin embargo, creo que ya he conseguido, inspirado por algún programa similar que he visto en Internet, resolver el ejercicio. En cuanto llegue a mi casa adjunto el script. Sin embargo, ahora tengo dudas sobre cómo afrontar este otro ejercicio:

"Crea una función que, dados n + 1 puntos, devuelva el polinomio interpolador en términos de sus coeficientes".
De nuevo gracias. Saludos.

Ése es más rutinario y creo recordar que lo hice alguna vez con ayuda de un ejemplo (para probar, no en plan serio). No es muy difícil porque es un sistema de ecuaciones al fin y al cabo. Busca en internet "Python polinomio interpolador" y vendrá; y así ves la idea.
En cambio, el problema de hallar la inversa con los adjuntos es que, si entendemos que el usuario, mediante un input, mete la dimensión que quiera (para que sea un programa un poco serio) pues hay que organizarse bien tomando los menores principales y programando la rutina para cada determinante; que puede ser de orden siete... o lo que sea, porque la inversa de una matriz de orden 2 sería una tontería, claro; eso te lo dice, entiendo, como idea para hacerlo después general.
No sé, veo que es un programa que hay que pensarlo despacio; y yo ahora mismo no puedo, si no, sí que te lo haría o te lo dejaría medio hecho.

Saludos.

13 Noviembre, 2021, 08:52 pm
Respuesta #4

DaniM

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 139
  • País: cz
  • Karma: +0/-0
Te lo he hecho yo usando recursividad como ha sugerido tu profesora. El programa acepta matrices cuadradas de cualquier dimensión, tiene manejo de errores y tests unitarios para cada función que he programado (por si te interesara reutilizarlas por separado para otros ejercicios; por ejemplo, la función detMatriz calcula el determinante de la matriz de cualquier dimensión que le pases). Lo he subido en mi GitHub:

Funciones: https://github.com/danielthetechie/Math-scripts/blob/main/matrices.py
Tests: https://github.com/danielthetechie/Math-scripts/blob/main/tests.py

Para ejecutarlo abre el fichero matrices.py y ejecuta la función matrizInversa, que acepta una matriz de cualquier dimensión como parámetro y te devuelve su inversa, en caso de tenerla.

Adjunto debajo el código:

Código: [Seleccionar]
"""Crea una función que, dada una matriz cuadrada A, compruebe si es invertible o no; y en caso afirmativo, calcule la inversa de A mediante el método de los adjuntos."""

def esMatrizCuadrada (mat):
filas = len (mat)
for fila in range (len (mat)):
columnas = len (mat[fila])
if (filas != columnas):
return False
return True

def det2x2 (mat):
if (not esMatrizCuadrada (mat) or len (mat) != 2):
return "Error: la matriz no es 2x2."

return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]

def detMatriz (mat):
n = len (mat)
if n == 1:
return mat[0][0]

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

resultado = 0

if n == 2:
resultado += det2x2 (mat)

else:
# Sea mat una matriz n x n, entonces all_mat_sub contendrá las submatrices (n - 1) x (n - 1).
all_mat_sub = []

mat_sub = []
row_sub = []

for i in range (n):
for j in range (1, n):
row_sub = mat[j][:i] + mat[j][i + 1:]
mat_sub.append (row_sub)
all_mat_sub.append (mat_sub)
resultado += (((-1)**(i + 2)) * mat[0][i] * detMatriz (mat_sub))
mat_sub = []

return resultado

# Dada una matriz A, devuelve la matriz que se obtiene de eliminar la fila i la columna j de A.
def matrizAdjuntaElementoIJ (i, j, mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

n = len (mat)
mat_sub = []
row_sub = []

for x in range (n):
if x == i:
continue
row_sub = mat[x][:j] + mat[x][j + 1:]
mat_sub.append (row_sub)

return mat_sub

def matrizAdjuntaTraspuesta (mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

n = len (mat)

mat_adj = []
mat_sub = []

for j in range (n):
for i in range (n):
mat_adj_ij = matrizAdjuntaElementoIJ (i, j, mat)
adj = ((-1)**(i + j + 2)) * detMatriz (mat_adj_ij)
mat_sub.append (adj)
mat_adj.append (mat_sub)
mat_sub = []

return mat_adj

def matrizInversa (mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

det_matriz = detMatriz (mat)

if (det_matriz == 0):
return "Esta matriz no tiene inversa."

n = len (mat)
mat_original = mat
mat = matrizAdjuntaTraspuesta (mat_original)

for i in range (n):
for j in range (n):
mat[i][j] = mat[i][j] / det_matriz

return mat

####################################
########### ¡A jugar! ##############
####################################

m6 = [
[4, 3, -1, 4, 2, 3],
[0, 8, -7, -5, 3, 2], 
[4, 3, -6, 8, 5, 1],
[7, -4, 0, 3, -9, 5],
[2, -1, 8, 6, -7, 0],
[3, 8, 11, 4, -2, 1]
]
print (matrizInversa (m6))


m7 = [
[1, 2, 3],
[3, 2, 1],
[1, 0, 1]
]
print ("\n")
print (matrizInversa (m7))

m1 = [
[2, 3],
[4, 5]
]
print ("\n")
print (matrizInversa (m1))

Fíjate que las matrices en el código las represento como arrays bidimensionales donde cada subarray representa una fila de la matriz. Por ejemplo, el array [[1, 2, 3], [4, 5, 6], [7, 8, 9]] representa la matriz

\( \begin{pmatrix}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9
\end{pmatrix} \)

Aquí dejo una captura de pantalla con tres matrices inversas que ha calculado el programa:


14 Noviembre, 2021, 07:51 pm
Respuesta #5

mathtruco

  • Moderador Global
  • Mensajes: 5,516
  • País: cl
  • Karma: +0/-0
  • Sexo: Masculino
  • El gran profesor inspira
Hola. Tres cosas antes de responder a tu pregunta:

1. Cuando tengas una nueva pregunta en el foro escríbela en un hilo nuevo y no como respuesta a uno anterior. Esto para que haya más orden en el foro, y también porque alguien que podría responder tu nueva pregunta al ver que está en un hilo muy largo puede no darse el tiempo de leer todo para ver de qué se trata, lo que hará que la respuesta a tu nueva pregunta demore más en llegar.

2. Todos estos ejercicios de programación puedes encontrarlos resueltos en internet. El problema, especialmente con python, es que hay muchas maneras de lograr lo mismo, por lo que no recomiendo aprender a programar mirando programas resueltos. Para aprender a programar hay que tratar de programar uno mismo, lo que puede llevar días.

3. Para programar algo en general te aconsejo comenzar con algo particular, un ejemplo de dimensión 2 o 3. Cuando tengas claro qué hacer en problemas pequeños escribes el código o pseudocódigo en un papel con los detalles que necesitas programar. Sólo cuando tengas lo anterior 100% claro comienzas a escribir en el pc.



Ahora sí, respondo a tu pregunta:

Aprecio tu ayuda. Sin embargo, creo que ya he conseguido, inspirado por algún programa similar que he visto en Internet, resolver el ejercicio. En cuanto llegue a mi casa adjunto el script. Sin embargo, ahora tengo dudas sobre cómo afrontar este otro ejercicio:

"Crea una función que, dados n + 1 puntos, devuelva el polinomio interpolador en términos de sus coeficientes".
De nuevo gracias. Saludos.

Tienes los puntos \( (x_1,y_1),\dots (x_{n+1},y_{n+1}) \) que satisfacen la ecuación polinomial

    \( y=a_0+a_1x+a_2x^2+\dots a_nx^n \)

donde \( a_i \) son independientes de \( x \). Reemplazando los puntos en la ecuación anterior obtienes el sistema de ecuaciones

    \( \begin{pmatrix}1&x_1&x_1^2&\dots&x_1^n\\ \vdots&\vdots&\vdots&\dots&\vdots \\ 1&x_{n+1}&x_{n+1}^2&\dots&x_{n+1}^n\end{pmatrix}\begin{pmatrix}a_0\\ \vdots \\ a_n\end{pmatrix}=\begin{pmatrix}y_1\\ \vdots \\ y_{n+1}\end{pmatrix} \).

Resolviendo este sistema lineal obtienes los coeficientes del polinomio pedido.

24 Noviembre, 2021, 07:50 am
Respuesta #6

lopezcurp

  • $$\Large \color{#6a84c0}\pi$$
  • Mensajes: 3
  • País: mx
  • Karma: +0/-0
    • CURP
Te lo he hecho yo usando recursividad como ha sugerido tu profesora. El programa acepta matrices cuadradas de cualquier dimensión, tiene manejo de errores y tests unitarios para cada función que he programado (por si te interesara reutilizarlas por separado para otros ejercicios; por ejemplo, la función detMatriz calcula el determinante de la matriz de cualquier dimensión que le pases). Lo he subido en mi GitHub:

Funciones: https://github.com/danielthetechie/Math-scripts/blob/main/matrices.py
Tests: https://github.com/danielthetechie/Math-scripts/blob/main/tests.py

Para ejecutarlo abre el fichero matrices.py y ejecuta la función matrizInversa, que acepta una matriz de cualquier dimensión como parámetro y te devuelve su inversa, en caso de tenerla.

Adjunto debajo el código:

Código: [Seleccionar]
"""Crea una función que, dada una matriz cuadrada A, compruebe si es invertible o no; y en caso afirmativo, calcule la inversa de A mediante el método de los adjuntos."""

def esMatrizCuadrada (mat):
filas = len (mat)
for fila in range (len (mat)):
columnas = len (mat[fila])
if (filas != columnas):
return False
return True

def det2x2 (mat):
if (not esMatrizCuadrada (mat) or len (mat) != 2):
return "Error: la matriz no es 2x2."

return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]

def detMatriz (mat):
n = len (mat)
if n == 1:
return mat[0][0]

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

resultado = 0

if n == 2:
resultado += det2x2 (mat)

else:
# Sea mat una matriz n x n, entonces all_mat_sub contendrá las submatrices (n - 1) x (n - 1).
all_mat_sub = []

mat_sub = []
row_sub = []

for i in range (n):
for j in range (1, n):
row_sub = mat[j][:i] + mat[j][i + 1:]
mat_sub.append (row_sub)
all_mat_sub.append (mat_sub)
resultado += (((-1)**(i + 2)) * mat[0][i] * detMatriz (mat_sub))
mat_sub = []

return resultado

# Dada una matriz A, devuelve la matriz que se obtiene de eliminar la fila i la columna j de A.
def matrizAdjuntaElementoIJ (i, j, mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

n = len (mat)
mat_sub = []
row_sub = []

for x in range (n):
if x == i:
continue
row_sub = mat[x][:j] + mat[x][j + 1:]
mat_sub.append (row_sub)

return mat_sub

def matrizAdjuntaTraspuesta (mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

n = len (mat)

mat_adj = []
mat_sub = []

for j in range (n):
for i in range (n):
mat_adj_ij = matrizAdjuntaElementoIJ (i, j, mat)
adj = ((-1)**(i + j + 2)) * detMatriz (mat_adj_ij)
mat_sub.append (adj)
mat_adj.append (mat_sub)
mat_sub = []

return mat_adj

def matrizInversa (mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

det_matriz = detMatriz (mat)

if (det_matriz == 0):
return "Esta matriz no tiene inversa."

n = len (mat)
mat_original = mat
mat = matrizAdjuntaTraspuesta (mat_original)

for i in range (n):
for j in range (n):
mat[i][j] = mat[i][j] / det_matriz

return mat

####################################
########### ¡A jugar! ##############
####################################

m6 = [
[4, 3, -1, 4, 2, 3],
[0, 8, -7, -5, 3, 2], 
[4, 3, -6, 8, 5, 1],
[7, -4, 0, 3, -9, 5],
[2, -1, 8, 6, -7, 0],
[3, 8, 11, 4, -2, 1]
]
print (matrizInversa (m6))


m7 = [
[1, 2, 3],
[3, 2, 1],
[1, 0, 1]
]
print ("\n")
print (matrizInversa (m7))

m1 = [
[2, 3],
[4, 5]
]
print ("\n")
print (matrizInversa (m1))

Fíjate que las matrices en el código las represento como arrays bidimensionales donde cada subarray representa una fila de la matriz. Por ejemplo, el array [[1, 2, 3], [4, 5, 6], [7, 8, 9]] representa la matriz

\( \begin{pmatrix}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9
\end{pmatrix} \)

Aquí dejo una captura de pantalla con tres matrices inversas que ha calculado el programa:



Excelente respuesta, estaba buscando algo parecido y me ha ayudado, gracias!

24 Noviembre, 2021, 09:53 am
Respuesta #7

DaniM

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 139
  • País: cz
  • Karma: +0/-0
Te lo he hecho yo usando recursividad como ha sugerido tu profesora. El programa acepta matrices cuadradas de cualquier dimensión, tiene manejo de errores y tests unitarios para cada función que he programado (por si te interesara reutilizarlas por separado para otros ejercicios; por ejemplo, la función detMatriz calcula el determinante de la matriz de cualquier dimensión que le pases). Lo he subido en mi GitHub:

Funciones: https://github.com/danielthetechie/Math-scripts/blob/main/matrices.py
Tests: https://github.com/danielthetechie/Math-scripts/blob/main/tests.py

Para ejecutarlo abre el fichero matrices.py y ejecuta la función matrizInversa, que acepta una matriz de cualquier dimensión como parámetro y te devuelve su inversa, en caso de tenerla.

Adjunto debajo el código:

Código: [Seleccionar]
"""Crea una función que, dada una matriz cuadrada A, compruebe si es invertible o no; y en caso afirmativo, calcule la inversa de A mediante el método de los adjuntos."""

def esMatrizCuadrada (mat):
filas = len (mat)
for fila in range (len (mat)):
columnas = len (mat[fila])
if (filas != columnas):
return False
return True

def det2x2 (mat):
if (not esMatrizCuadrada (mat) or len (mat) != 2):
return "Error: la matriz no es 2x2."

return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]

def detMatriz (mat):
n = len (mat)
if n == 1:
return mat[0][0]

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

resultado = 0

if n == 2:
resultado += det2x2 (mat)

else:
# Sea mat una matriz n x n, entonces all_mat_sub contendrá las submatrices (n - 1) x (n - 1).
all_mat_sub = []

mat_sub = []
row_sub = []

for i in range (n):
for j in range (1, n):
row_sub = mat[j][:i] + mat[j][i + 1:]
mat_sub.append (row_sub)
all_mat_sub.append (mat_sub)
resultado += (((-1)**(i + 2)) * mat[0][i] * detMatriz (mat_sub))
mat_sub = []

return resultado

# Dada una matriz A, devuelve la matriz que se obtiene de eliminar la fila i la columna j de A.
def matrizAdjuntaElementoIJ (i, j, mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

n = len (mat)
mat_sub = []
row_sub = []

for x in range (n):
if x == i:
continue
row_sub = mat[x][:j] + mat[x][j + 1:]
mat_sub.append (row_sub)

return mat_sub

def matrizAdjuntaTraspuesta (mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

n = len (mat)

mat_adj = []
mat_sub = []

for j in range (n):
for i in range (n):
mat_adj_ij = matrizAdjuntaElementoIJ (i, j, mat)
adj = ((-1)**(i + j + 2)) * detMatriz (mat_adj_ij)
mat_sub.append (adj)
mat_adj.append (mat_sub)
mat_sub = []

return mat_adj

def matrizInversa (mat):

if (not esMatrizCuadrada (mat)):
return "Error: la matriz no es cuadrada."

det_matriz = detMatriz (mat)

if (det_matriz == 0):
return "Esta matriz no tiene inversa."

n = len (mat)
mat_original = mat
mat = matrizAdjuntaTraspuesta (mat_original)

for i in range (n):
for j in range (n):
mat[i][j] = mat[i][j] / det_matriz

return mat

####################################
########### ¡A jugar! ##############
####################################

m6 = [
[4, 3, -1, 4, 2, 3],
[0, 8, -7, -5, 3, 2], 
[4, 3, -6, 8, 5, 1],
[7, -4, 0, 3, -9, 5],
[2, -1, 8, 6, -7, 0],
[3, 8, 11, 4, -2, 1]
]
print (matrizInversa (m6))


m7 = [
[1, 2, 3],
[3, 2, 1],
[1, 0, 1]
]
print ("\n")
print (matrizInversa (m7))

m1 = [
[2, 3],
[4, 5]
]
print ("\n")
print (matrizInversa (m1))

Fíjate que las matrices en el código las represento como arrays bidimensionales donde cada subarray representa una fila de la matriz. Por ejemplo, el array [[1, 2, 3], [4, 5, 6], [7, 8, 9]] representa la matriz

\( \begin{pmatrix}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9
\end{pmatrix} \)

Aquí dejo una captura de pantalla con tres matrices inversas que ha calculado el programa:



Excelente respuesta, estaba buscando algo parecido y me ha ayudado, gracias!

De nada, me alegro de que sea de utilidad. :)