Classes para integrais
Equações para a integração numérica
Existem várias equações para a integração numérica e todas podem ser colocadas em uma notação comum:
sendo: $w_i$ os pesos e $x_i$ os pontos (específicos para uma certa equação).
A regra do trapézio tem $h = (b - a)/(n - 1) e:
A regra do ponto médio tem $ h = (b - a)/n $ e:
A regra de Simpson tem $h = (b - a)/(n - 1)$ e:
Quais devem ser implementadas em ua classe hierárquica?
- Uma equação para integração numérica pode ser implementada em uma classe: $a$, $b$ e $n$ são atributos e um método
integracao
avalia a equação; - Todas as tais classes são muito similares: a avaliação de $\sum_{j} w_j f(x_j)$ é a mesma, somente a definição dos pontos e pesos diferem entre as classes;
- Lembrete: código duplicado é um péssima ideia;
- Ideia geral de OO: colocar o código comum a várias classes em uma superclasse e herdá-lo;
- Aqui colocaremos $\sum_{j} w_j f(x_j)$ em uma superclasse (método
integracao
); - Subclasses extendem a superclasse com códigos específicos de uma equação matemática, isto é, $w_i$ e $x_i$ em um método de uma classe
regra_construtor
.
A superclasse para integração
class Integrador:
def __init__(self, a, b, n):
self.a, self.b, self.n = a, b, n
self.pontos, self.pesos = self.metodo_construtor()
def metodo_construtor(self):
raise NotImplementedError('Nenhuma regra na classe %s' % \
self.__class__.__name__)
def integracao(self, f):
s = 0
for i in range(len(self.pesos)):
s += self.pesos[i]*f(self.pontos[i])
return s
def integracao_vetorizada(self, f):
# f deve ser vetorizado para isso funcionar
return dot(self.pesos, f(self.pontos))
Subclasse regra dos trapézios
class Trapezios(Integrador):
def metodo_construtor(self):
h = (self.b - self.a)/float(self.n - 1)
x = linspace(self.a, self.b, self.n)
w = zeros(len(x))
w[1:-1] += h
w[0] = h/2; w[-1] = h/2
return x, w
Subclasse regra de Simpson
class Simpson(Integrador):
def metodo_construtor(self):
if self.n % 2 != 1:
print 'n=%d deve ser ímpar, 1 é adicionado' % self.n
self.n += 1
x = np.linspace(self.a, self.b, self.n)
h = (self.b - self.a)/float(self.n - 1)*2
w = np.zeros(len(x))
w[0:self.n:2] = h*1.0/3
w[1:self.n-1:2] = h*2.0/3
w[0] /= 2
w[-1] /= 2
return x, w
O fluxo do programa
Resumo dos princípios da orientação à objeto
- Uma subclasse herda tudo da superclasse;
- Quando utilizar subclasses e superclasses?
- se o código comum a várias classes pode ser colocado em uma superclasse;
- se o problema possui um conceito pai-filho natural;
- O fluxo do programa pula entre a superclasse e a subclasse;
- Demora tempo para dominar quando e como utilizar OO;
- Dica: estude exemplos!
Tarefa
Integre e derive a seguinte equação para $m = 0$, $m = 1/4$, $m=1/2$, $m=1/8$, $m = 1$, $m = 2$, $m = 4$ e $m=16$:
Objetivos:
- Código em superclasses e subclasses com funções de teste;
- GUI utilizando o Tkinter para a inserção do valor de $m$, mostrar o valor cálculado e vizualizar um gráfico da taxa de convergência;
- O gráfico da taxa de convergência deve mostrar, em escala logarítmica valores variados de $n$ em x e do erro em y para as regras de integracao do ponto central, trapézio, Simpson e Gauss Legendre;
- Os valores de $n$ são: 10, 20, 40, 80, 160, 320, 640