Seja $\mathbf{T}=\{(x_0,y_0),\dots , (x_k,y_k)\}$ uma tabela regular e $\{g_0,\dots , g_n\}$ uma família de funções $g_i: I \to \mathbb{R}$. O problema geral de MMQ é encontrar uma função $g$ que seja combinação linear da família $\{g_i\}$ e que minimize o resíduo quadrático em relação à tabela $\mathbf{T}$. Lembro que $\text{Res}(g,\mathbf{T})=\sum_{j=0}^k (g(x_j)-y_j)^2$.
Note que o resíduo será zero se, e somente se, tivermos $g(x_j) = y_j$ para todo $0\leq j\leq k$. e isto equivale a dizer que existem números $a_0,\dots , a_n$ tais que $\sum_{i=0}^n a_ig_i(x_j) = y_j$ pra todo $j \in \{0,\dots,k\}$. Uma outra interpretação desta equação é que o vetor coluna $$ \mathbf{a} = \begin{bmatrix} a_0 \\ \vdots \\ a_n \end{bmatrix} $$ satisfaz o sistema linear $P\mathbf{a} = \mathbf{y}$ onde $$ P = \begin{pmatrix} g_0(x_0) & g_1(x_0) & \cdots & g_n(x_0) \\ \vdots & \vdots & \vdots & \vdots \\ g_0(x_k) & g_1(x_k) & \dots & g_n(x_k) \end{pmatrix} \text{ e } \mathbf{y} =\begin{pmatrix} y_0 \\ \vdots \\ y_k \end{pmatrix} $$ Chamaremos esta matriz $P$ de matriz de projeto do problema de MMQ.
Se todas as colunas da matriz $P$ forem li diremos que o problema tem posto máximo e a solução do problema geral é encontrada resolvendo o sistema normal $A\mathbf{a} = \mathbf{b}$ onde a matriz $A$ tem os coeficientes $a_{ij} = \langle g_i , g_j \rangle = \sum_{l=0}^kg_i(x_l)g_j(x_l)$ e $b_i = \sum_{l=0}^k y_lg_i(x_l) = \langle \mathbf{y},g_i \rangle$
polyfit()
e lstsq()
do NUMPY¶A primeira função recebe como parâmetros os pontos da tabela e o grau do polinômio e devolve uma lista com os coeficientes do polinômio.
import numpy as np
tabela = [(0,1),(1,2.3),(2,5.4),(3,-1), (4,-5.5)]
x = np.array([p[0] for p in tabela])
y = np.array([p[1] for p in tabela])
z = np.polyfit(x,y,3)
p = np.poly1d(z)
p
poly1d([ 0.00833333, -1.55714286, 4.4702381 , 0.67571429])
p(0)
0.67571428571428682
p(1)
3.5971428571428605
%matplotlib inline
from matplotlib.pyplot import plot,grid
t=np.linspace(0,4.5,100)
plot(x,y,"ro",t,p(t))
grid()
A função lstsq()
recebe como entrada a matriz de projeto $A$ que é uma matriz $(n+1)\times (k+1)$ e um vetor $y\in \mathbb{R}^{k+1}$
from numpy.linalg import lstsq
f0 = lambda x: 1
f1 = lambda x: np.cos(x)
f2 = lambda x: np.sin(x)
# vamos usar a mesma tabela anterior e construir a matriz de projeto
A = np.array([[f0(u) for u in x] ,[f1(u) for u in x],[f2(u) for u in x]]).T
print(A)
[[ 1. 1. 0. ] [ 1. 0.54030231 0.84147098] [ 1. -0.41614684 0.90929743] [ 1. -0.9899925 0.14112001] [ 1. -0.65364362 -0.7568025 ]]
result = lstsq(A,y)
result[0]
array([-0.7054306 , 0.66399755, 5.34945131])
g = lambda x: result[0][0]*f0(x) + result[0][1]*f1(x) + result[0][2]*f2(x)
plot(x,y, "ro",t,g(t))
grid()
# residuo
result[1]
array([ 7.07862146])
plot(x,y, "ro",t,g(t),t,p(t))
[<matplotlib.lines.Line2D at 0xb15a70ec>, <matplotlib.lines.Line2D at 0xb150edec>, <matplotlib.lines.Line2D at 0xb14dd68c>]