O Método dos Mínimos Quadrados consiste em, dado um conjunto de pontos , determinar uma função que melhor se aproxime de . Geralmente, escrevemos a função como uma combinação linear de funções , tal que: .

Primeiramente vamos definir o método para o caso básico no qual a função é uma combinação linear de funções e , após isso vamos generalizar o método para qualquer número de funções.

Duas variáveis

O problema de quadrados mínimos lineares discreto de duas variáveis consiste em, dadas duas funções e , determinar duas constantes reais e tais que a função esteja o mais próximo possível dos pontos conhecidos. Naturalmente, para determinar o quão próximas são as aproximações é necessário definir o erro, que pode ser definido como . Dessa forma, é possível transformar o problema em um problema de otimização da forma:

Resolvendo esse problema de otimização, obtém-se o seguinte sistema linear, que permite encontrar os valores das constantes e que minimizam o erro da estimativa para a função :

Esse método pode ser facilmente implementado da seguinte forma:

import numpy as np
 
x = [-0.6975, -0.6762, 0.0176, 0.4512, 0.7559]
fx = [2.0840, 2.0330, 0.8472, 0.6773, 0.4318]
 
 
def g1(x):
    return 1
    # return np.sin(x)
 
 
def g2(x):
    return np.exp(-x)
    # return np.cos(x)
 
 
def a11(x):
    n = 0
 
    for i in range(len(x)):
        n = n + (g1(x[i]) ** 2)
 
    return n
 
 
def a12(x):
    n = 0
 
    for i in range(len(x)):
        n = n + (g1(x[i]) * g2(x[i]))
 
    return n
 
 
def a22(x):
    n = 0
 
    for i in range(len(x)):
        n = n + (g2(x[i]) ** 2)
 
    return n
 
 
def y1(x, fx):
    n = 0
 
    for i in range(len(x)):
        n = n + (g1(x[i]) * fx[i])
 
    return n
 
 
def y2(x, fx):
    n = 0
 
    for i in range(len(x)):
        n = n + (g2(x[i]) * fx[i])
 
    return n
 
 
A = [[a11(x), a12(x)], [a12(x), a22(x)]]
b = [y1(x, fx), y2(x, fx)]
 
print("A = ", A)
print("b = ", b)
 
result = np.linalg.solve(A, b)
 
print("a1 = ", result[0])
print("a2 = ", result[1])

Caso geral

No caso geral, o problema de quadrados mínimos consiste em obter coeficientes que minimizem a seguinte função:

sendo a função definida como:

Resolvendo esse problema de otimização através de derivadas parciais, obtém-se equações (as derivadas parciais igualadas a ). Manipulando as equações, é possível obter o seguinte sistema linear, que permite encontrar o valor dos coeficientes :

A implementação desse método consiste na construção e resolução deste sistema linear, como pode ser verificado a seguir:

import numpy as np
import csv
 
 
def termoA(x, g, i, j, m):
    num = 0
 
    for k in range(0, m):
        num = num + (g[i](x[k]) * g[j](x[k]))
 
    return num
 
 
def termoB(x, fx, g, i, m):
    num = 0
 
    for k in range(0, m):
        num = num + (fx[k] * g[i](x[k]))
 
    return num
 
 
def matrizAumentada(x, fx, g, n):
    m = len(x)
    A = np.empty((n, n))
    b = np.empty((n))
 
    for i in range(0, n):
        for j in range(i, n):
            A[i][j] = termoA(x, g, i, j, m)
 
            if i != j:
                A[j][i] = A[i][j]
 
        b[i] = termoB(x, fx, g, i, m)
 
    return A, b
 
 
x = [-1, -0.5, 0, 0.5, 1]
fx = [8.4, 2.7, 2.6, 2.8, 5.6]
g = [lambda x: 1, lambda x: np.sin(np.pi * x), lambda x: x * np.cos(np.pi * x)]
n = len(g)
 
 
A, b = matrizAumentada(x, fx, g, n)
 
 
a = np.linalg.solve(A, b)
 
print("A: ", A)
print("b: ", b)
print("Coeficientes: ", a)