Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Como aplicar classes a polinômios no python?

0 votos
40 visitas
perguntada Ago 9 em Ciência da Computação por Sergio Costa (11 pontos)  
editado Ago 22 por Sergio Costa

Aplicação específica para o polinômio de ordem \(N\) originado da série de Taylor sobre a função \(f(x)=e^x\) ao redor de \(a=0\) (Maclaurin). Questão 7.23 do livro "A primer with Scientific Programming with Python: 6", por Hans Petter Langtangen (Capítulo 7, pág 480).

Compartilhe

1 Resposta

0 votos
respondida Ago 9 por Sergio Costa (11 pontos)  
editado Set 19 por Sergio Costa

Olá, amigos,

A questão solicita a aplicação de classes sobre o seguinte polinômio \( p(x)=\sum_{k=0}^{N}\frac{x^{k}}{k!} \), polinômio de Taylor de grau \(N\) originado de \(f(x)=e^x\). O livro dividiu o exercício em quatro partes:

  1. Importar a classe Polynomial da seção 7.3.7;
  2. Ler valores de vetores de X e de N da linha de comando;
  3. Criar objeto Polynomial para cada elemento de N, que corresponda a um polinômio de Taylor do enunciado;
  4. Apresentar os valores de \(p(x)\), de \(N\) e o valor de \(e^x\) para X = 0.5, 3, 10 e N = 2, 5, 10, 15, 25.

Em primeiro lugar, cumpre demonstrar como se chegou em \(p(x)=\sum_{k=0}^{N}\frac{x^{k}}{k!} \). Esta expressão se trata de um polinômio de Taylor de ordem \(N\) (uma aproximação do valor de uma função) ao redor de \(a=0\), a partir da série abaixo:

\[f(x)=\sum_{n=0}^{\infty}\frac{f^{(n)}(a)}{n!}(x-a)^{n}\]

Onde, \(f^{(n)}(a)\) é a derivada de ordem \(n\) no ponto \(a\). Na questão 7.23, a função original é \(e^x\), sendo utilizado um caso particular do polinômio de Taylor quando \(a=0\), atribuído a Maclaurin.


Passada a parte teórica, vamos a resolução da questão:

Na classe Polynomial, os coeficientes de um dado polinômio são definidos como elementos de um vetor que o representa, onde para cada grau é armazenado em sequência o respectivo coeficiente (mesmo que \(0\)). Por exemplo: \(p(x) = 3x^2 + 4\) seria armazenado como um vetor \(z = [4, 0, 3]\).

Para utilizar essa classe, criei uma função que armazenava em uma lista os coeficientes de \(p(x)=\sum_{k=0}^{N}\frac{x^{k}}{k!} \) no arquivo maclaurin.py.

#calcula um fatorial de maneira recursiva
def fatorial(n):
    if n > 1:
       return n*fatorial(n-1)        
    else:
        return 1 
#monta uma lista de coeficientes da série de Maclaurin para e^x    
def Maclaurin(n):
    coeficientes = list()
    for i in range(n+1):
        coeficientes.append(1/fatorial(i))
    return coeficientes

Abaixo, segue classe Polynomial , cujos argumentos são os coeficientes de um dado polinômio, conforme a seção 7.3.7 do livro (polynomial.py).

class Polynomial(object):
#Define coeficientes para um dado polinômio
    def __init__(self, coefficients):
        self.coeff = coefficients
#Calcula o valor do polinômio
    def __call__(self, x):
        s = 0
        for i in range(len(self.coeff)):
            s += self.coeff[i]*x**i
        return s

Por último, foi criado o programa que utilizava a classe Polynomial e o método especial __call__ para calcular os valores de \(p(x)\) para x = 0.5, 3, 10 e N = 2, 5, 10, 15, 25.

import polynomial
import maclaurin
import math

def exercicio(x,n):
    lista = maclaurin.Maclaurin(n)
    objeto = polynomial.Polynomial(lista)
    return objeto.__call__(x)

if __name__ == "__main__":
    X=[0.5, 3, 10]
    N=[2, 5, 10, 15, 25]
    [print('Para x=%g e n=%d: p(x)=%.10f e e^x=%.10f.' 
     %(x,n,exercicio(x,n), math.exp(x))) for x in X for n in N] 

Resultados:

    Para x=0.5 e n=2: p(x)=1.6250000000 e e^x=1.6487212707.
    Para x=0.5 e n=5: p(x)=1.6486979167 e e^x=1.6487212707.
    Para x=0.5 e n=10: p(x)=1.6487212707 e e^x=1.6487212707.
    Para x=0.5 e n=15: p(x)=1.6487212707 e e^x=1.6487212707.
    Para x=0.5 e n=25: p(x)=1.6487212707 e e^x=1.6487212707.
    Para x=3 e n=2: p(x)=8.5000000000 e e^x=20.0855369232.
    Para x=3 e n=5: p(x)=18.4000000000 e e^x=20.0855369232.
    Para x=3 e n=10: p(x)=20.0796651786 e e^x=20.0855369232.
    Para x=3 e n=15: p(x)=20.0855344310 e e^x=20.0855369232.
    Para x=3 e n=25: p(x)=20.0855369232 e e^x=20.0855369232.
    Para x=10 e n=2: p(x)=61.0000000000 e e^x=22026.4657948067.
    Para x=10 e n=5: p(x)=1477.6666666667 e e^x=22026.4657948067.
    Para x=10 e n=10: p(x)=12842.3051146384 e e^x=22026.4657948067.
    Para x=10 e n=15: p(x)=20952.8869686065 e e^x=22026.4657948067.
    Para x=10 e n=25: p(x)=22026.0763608911 e e^x=22026.4657948067.

De antemão, peço desculpas por quaisquer imprecisões e falhas na explicação e na programação. Em relação ao ponto 2 da questão (ler valores X e N da linha de comando), poderia ter usado uma função input e depois separar os valores da string em listas para X e para N. Para simplificação da resolução, preferi colocar os vetores X e N diretamente no programa.

comentou Nov 5 por VITOR B BORGES (1 ponto)  
O programa não contém nenhuma falha ou imprecisão, a solução segue à risca o que foi pedido no enunciado e o código está completamente replicável. Foi a escolha correta definir os vetores x e N na linha de comando. Apenas à título de curiosidade irei deixar aqui o código que os lê como input():

x = list(map(float, input('Entradas do vetor x: ').split()))
N = list(map(float, input('Entradas do vetor N: ').split()))
...