Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # creación de la clase polinomio
- class Polinomio:
- def __init__(self, coeficientes):
- self.coeficientes = coeficientes
- # constructor del polinomio
- def __str__(self):
- # podríamos haber definido el polinomio como una cadena vacía también
- terminos = []
- # al usar enumerate podemos asignar 2 variables al bucle for (i -> posición), (coef -> el coeficiente) en lugar de usar una variable auxiliar de contador
- for i, coef in enumerate(self.coeficientes):
- if coef == 0:
- # al contrario de break, continue, nos hace saltar directamente a la siguiente iteración del for
- continue
- potencia = (len(self.coeficientes)-1) - i
- # condiciones
- if potencia == 0:
- terminos.append(f"{coef}")
- elif potencia == 1:
- if coef == 1:
- terminos.append("x")
- elif coef == -1:
- terminos.append("-x")
- else:
- terminos.append(f"{coef}x")
- else:
- if coef == 1:
- terminos.append(f"x^{potencia}")
- elif coef == -1:
- terminos.append(f"-x^{potencia}")
- else:
- terminos.append(f"{coef}x^{potencia}")
- #unimos terminos de la lista con + y reemplazamos "+ -" por "- " en caso de que los coeficientes sean negativos
- polinomio = ' + '.join(terminos).replace("+ -","- ")
- if not terminos:
- return "0"
- return polinomio
- def evaluar(self, x):
- coeficientes = self.coeficientes # se obtienen los coeficientes del polinomio
- imagen = 0
- # se recorre la lista de coeficientes para calcular el valor del polinomio
- for i, coef in enumerate(coeficientes):
- # se calcula el término correspondiente y se suma a la imagen
- if (len(coeficientes)-1-i) != 0:
- imagen += pow(x, len(coeficientes)-1-i) * coef
- else:
- # cuando es el término independiente (potencia 0), se suma directamente el coeficiente
- imagen += coef
- return imagen
- def mul_real(self, x):
- coeficientes_copia = []
- # copiamos el polinomio original a una copia para no modificarlo
- for coef in self.coeficientes:
- coeficientes_copia.append(coef)
- # se multiplica cada coeficiente por el número real 'x'
- for i, coef in enumerate(coeficientes_copia):
- coeficientes_copia[i] = coef*x # actualiza el coeficiente multiplicándolo por x
- return Polinomio(coeficientes_copia)
- def pol_opuesto(self):
- coeficientes_copia = []
- # hacemos la copia
- for coef in self.coeficientes:
- coeficientes_copia.append(coef)
- # se cambia el signo de cada coeficiente para obtener el polinomio opuesto
- for i, coef in enumerate(coeficientes_copia):
- coeficientes_copia[i] = coef*(-1) # cambia el signo del coeficiente
- return Polinomio(coeficientes_copia) # devuelve el polinomio opuesto
- def derivada(self):
- # crear una copia de la lista de coeficientes para manipularla
- coeficientes_copia = []
- for coef in self.coeficientes:
- coeficientes_copia.append(coef)
- # eliminar el término constante ya que su derivada es 0
- coeficientes_copia.pop()
- # lista para almacenar los coeficientes derivados
- coeficientes_derivados = []
- # calcular la derivada de cada término del polinomio
- for i, coef in enumerate(coeficientes_copia):
- grado = len(coeficientes_copia)-i # determinar el grado del término
- coef = coef*grado
- coeficientes_derivados.append(coef)
- # devolver un nuevo polinomio con los coeficientes derivados
- return Polinomio(coeficientes_derivados)
- def suma_pol(self, other):
- # invertir las listas de coeficientes para trabajar de menor a mayor grado
- polinomio1 = list(reversed(self.coeficientes))
- polinomio2 = list(reversed(other.coeficientes))
- max_longitud = max(len(polinomio1), len(polinomio2))
- polinomio1_l = polinomio1 + (max_longitud - len(polinomio1))*[0]
- polinomio2_l = polinomio2 + (max_longitud - len(polinomio2))*[0]
- # sumar los coeficientes correspondientes de los dos polinomios
- coeficientes_suma = []
- for i in range(max_longitud):
- coeficientes_suma.append(polinomio1_l[i] + polinomio2_l[i])
- # invertir de nuevo para obtener el orden correcto de coeficientes
- coeficientes_suma = list(reversed(coeficientes_suma))
- return Polinomio(coeficientes_suma)
- def resta_pol(self, other):
- polinomio1 = list(reversed(self.coeficientes))
- polinomio2 = list(reversed(other.coeficientes))
- max_longitud = max(len(polinomio1), len(polinomio2))
- polinomio1_l = polinomio1 + (max_longitud - len(polinomio1))*[0]
- polinomio2_l = polinomio2 + (max_longitud - len(polinomio2))*[0]
- # restar los coeficientes correspondientes
- coeficientes_resta = []
- for i in range(max_longitud):
- coeficientes_resta.append(polinomio1_l[i] - polinomio2_l[i])
- coeficientes_resta = list(reversed(coeficientes_resta))
- return Polinomio(coeficientes_resta)
- def mul_pol(self, other):
- polinomio1 = list(reversed(self.coeficientes))
- polinomio2 = list(reversed(other.coeficientes))
- # se inicializa el resultado con ceros para almacenar los coeficientes resultantes
- resultado = [0] * (len(polinomio1) + len(polinomio2) - 1)
- for i, coef1 in enumerate(polinomio1):
- for j, coef2 in enumerate(polinomio2):
- resultado[i+j] += coef1 * coef2
- # eliminar ceros al final que no representan términos
- while len(resultado) > 1 and resultado[-1] == 0:
- resultado.pop()
- # devolver nuevo polinomio con coeficientes invertidos a su orden original
- return Polinomio(list(reversed(resultado)))
- def div_pol(self, other):
- polinomio1 = list(reversed(self.coeficientes))
- polinomio2 = list(reversed(other.coeficientes))
- # determinar grados de los polinomios para guiar la división
- grado_dividendo = len(polinomio1) - 1
- grado_divisor = len(polinomio2) - 1
- # inicializar cociente con ceros
- cociente = [0] * max(1, grado_dividendo - grado_divisor + 1)
- while grado_dividendo >= grado_divisor and grado_dividendo >= 0:
- # calcular factor del término actual del cociente
- factor = polinomio1[grado_dividendo] / polinomio2[grado_divisor]
- cociente[grado_dividendo - grado_divisor] = factor
- # restar el múltiplo del divisor del dividendo
- for i in range(len(polinomio2)):
- if grado_dividendo - i < 0:
- break
- polinomio1[grado_dividendo - i] -= polinomio2[grado_divisor - i] * factor
- # ajustar grado del dividendo después de la substracción
- while grado_dividendo >= 0 and (grado_dividendo >= len(polinomio1) or polinomio1[grado_dividendo] == 0):
- grado_dividendo -= 1
- # recolectar y ajustar los términos restantes como el resto
- resto = list(reversed(polinomio1[:max(0, grado_dividendo + 1)]))
- # convertimos los coeficientes a enteros si son enteros exactos para limpieza de n.0
- for i, coef in enumerate(resto):
- if resto[i] % 1 == 0:
- resto[i] = int(resto[i])
- for i, coef in enumerate(cociente):
- if coef % 1 == 0:
- cociente[i] = int(cociente[i])
- # se eliminan ceros innecesarios del cociente
- while len(cociente) > 1 and cociente[-1] == 0:
- cociente.pop()
- return Polinomio(list(reversed(cociente))), Polinomio(resto)
- # Los método de aquí en adelante han sido estructurados para ser usados dentro del método factorizar()
- # El razonamiento que se ha hecho para poder por lo menos factorizar polinomios con soluciones racionales ha sido
- # 1) MCD -> Simplificamos -> Ruffini -> Iteramos
- def mcd(self):
- # definición de la función euclides para calcular el mcd de dos números
- def euclides(a, b):
- # bucle mientras b sea diferente de cero
- while b != 0:
- # actualizamos los valores de a y b usando el algoritmo de euclides
- a, b = b, a % b
- return a
- # inicializamos mcd con el primer coeficiente del polinomio
- mcd = self.coeficientes[0]
- # iteramos sobre los coeficientes del polinomio
- for coef in self.coeficientes[1:]:
- # actualizamos el mcd con el mcd del coeficiente actual y el mcd acumulado
- mcd = euclides(mcd, coef)
- return mcd
- def simplificar(self):
- # obtenemos el mcd de los coeficientes del polinomio
- mcd = self.mcd()
- # solo simplificamos si el mcd es diferente de 1
- if mcd != 1:
- nuevos_coeficientes = [] # lista para almacenar los nuevos coeficientes
- # dividimos cada coeficiente por el mcd y lo añadimos a la lista de nuevos coeficientes
- for coef in self.coeficientes:
- nuevos_coeficientes.append(coef // mcd)
- # actualizamos los coeficientes del polinomio con los nuevos coeficientes simplificados
- self.coeficientes = nuevos_coeficientes
- def raices_racionales(self):
- # inicialización de la lista para almacenar posibles numeradores
- numerador = []
- # bucle para encontrar todos los enteros entre el negativo y positivo del último coeficiente
- for i in range(-abs(self.coeficientes[-1]), abs(self.coeficientes[-1]) + 1):
- if i != 0: # excluimos el cero ya que no es un candidato válido para el numerador
- numerador.append(i)
- # inicialización de la lista para almacenar posibles denominadores
- denominador = []
- # bucle para encontrar todos los divisores del primer coeficiente
- for i in range(1, abs(self.coeficientes[0]) + 1):
- if self.coeficientes[0] % i == 0: # si i es un divisor de coeficientes[0]
- denominador.append(i)
- # utilizamos un conjunto para evitar repetir candidatos
- candidatos = set()
- # doble bucle para dividir todos los numeradores posibles entre los denominadores
- for numerador_valor in numerador:
- for denominador_valor in denominador:
- candidato = numerador_valor // denominador_valor
- candidatos.add(candidato) # añadimos el candidato al conjunto de candidatos
- # devolvemos el conjunto de candidatos posibles
- return candidatos
- def ruffini(self, raiz):
- # inicialización de la lista para almacenar los coeficientes resultantes
- resultado = []
- # el primer coeficiente siempre es parte del resultado
- resultado.append(self.coeficientes[0])
- # aplicamos la regla de ruffini para encontrar el resto de coeficientes
- for coef in self.coeficientes[1:]:
- # multiplicamos el último elemento de resultado por la raíz y sumamos el coeficiente actual
- resultado.append(resultado[-1] * raiz + coef)
- # devolvemos dos cosas: el polinomio resultante y el residuo
- # el polinomio resultante es todos menos el último término de resultado
- # el último término de resultado es el residuo
- return Polinomio(resultado[:-1]), resultado[-1]
- def factorizar(self):
- # copia de los coeficientes para evitar modificar el polinomio original
- coeficientes_copia = []
- for coef in self.coeficientes:
- coeficientes_copia.append(coef)
- # creación de una nueva variable de clase Polinomio con la copia de los coeficientes
- coeficientes_copia = Polinomio(coeficientes_copia)
- # simplificación del polinomio si es necesario
- coeficientes_copia.simplificar()
- # inicializamos la lista para almacenar los factores del polinomio
- factores = []
- # bucle para encontrar todos los factores
- while len(coeficientes_copia.coeficientes) > 1:
- # búsqueda de raíces racionales del polinomio
- raices = coeficientes_copia.raices_racionales()
- raiz_encontrada = None
- # iteramos a través de las raíces potenciales
- for r in raices:
- # uso del método de ruffini para reducir el polinomio por una raíz potencial
- polinomio_reducido, resto = coeficientes_copia.ruffini(r)
- if resto == 0: # si el resto es 0, r es una raíz del polinomio
- raiz_encontrada = r
- # actualizamos los coeficientes del polinomio para reflejar la división
- coeficientes_copia.coeficientes = polinomio_reducido.coeficientes
- # registro del factor encontrado
- factores.append(f"x - {r}")
- break # salimos del bucle ya que encontramos una raíz válida
- if raiz_encontrada is None:
- break # si no se encuentran más raíces racionales, terminamos el bucle
- # devolución de la lista de factores encontrados
- return factores
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement