Escreva um programa que leia o arquivo dados_ajuste.dat contendo valores de x e y e ajuste uma função linear a esses dados usando o método de mínimos quadrados.

Passo 1

O enunciado pede para escrever um programa que leia um arquivo chamado dados_ajuste.dat contendo em cada linha um par de valores (x,y) e ajuste uma reta do tipo
y = m\,x + b
a esses pontos usando o método dos mínimos quadrados. Vamos precisar da teoria de regressão linear simples, que fornece fórmulas fechadas para o coeficiente angular m e o coeficiente linear b.

Passo 2

Na regressão linear simples, dados N pontos (x_i,y_i), definimos as somas
S_x = \sum_{i=1}^N x_i, \quad S_y = \sum_{i=1}^N y_i, \quad S_{xx} = \sum_{i=1}^N x_i^2, \quad S_{xy} = \sum_{i=1}^N x_i\,y_i.
Então o coeficiente angular m e o coeficiente linear b são dados por
m = \frac{N\,S_{xy} - S_x\,S_y}{N\,S_{xx} - (S_x)^2}, \quad b = \frac{S_y - m\,S_x}{N}.

Passo 3

O algoritmo do programa será:
  1. Abrir o arquivo dados_ajuste.dat em modo leitura.
  2. Inicializar contadores: N=0, S_x=0, S_y=0, S_{xx}=0, S_{xy}=0.
  3. Para cada linha do arquivo:
    • Fazer o parsing dos dois números reais x e y.
    • Incrementar N \leftarrow N+1.
    • Atualizar S_x \leftarrow S_x + x, \quad S_y \leftarrow S_y + y, \quad S_{xx} \leftarrow S_{xx} + x^2, \quad S_{xy} \leftarrow S_{xy} + x\,y.
  4. Fechar o arquivo.

Passo 4

Depois de computar as somas e N, aplicar diretamente as fórmulas
m = \frac{N\,S_{xy} - S_x\,S_y}{N\,S_{xx} - (S_x)^2}, \quad b = \frac{S_y - m\,S_x}{N},
e exibir os valores de m e b. Se o denominador em m for zero, deve-se tratar como caso degenerado (por exemplo, exibindo uma mensagem de erro).

Resposta

# Programa de ajuste linear por mínimos quadrados
# Lê o arquivo 'dados_ajuste.dat' e calcula m e b para y = m*x + b

def main():
    nome_arquivo = 'dados_ajuste.dat'
    try:
        with open(nome_arquivo, 'r') as arquivo:
            N = 0
            Sx = Sy = Sxx = Sxy = 0.0

            for linha in arquivo:
                linha = linha.strip()
                if not linha or linha.startswith('#'):
                    continue  # pula linhas vazias ou comentários
                x_str, y_str = linha.split()
                x = float(x_str)
                y = float(y_str)

                N += 1
                Sx += x
                Sy += y
                Sxx += x*x
                Sxy += x*y

        if N == 0:
            print("Arquivo vazio ou sem dados válidos.")
            return

        denom = N*Sxx - Sx*Sx
        if abs(denom) < 1e-12:
            print("Erro: denominador zero no cálculo de m (pontos verticais ou todos x iguais).")
            return

        m = (N*Sxy - Sx*Sy) / denom
        b = (Sy - m*Sx) / N

        print(f"Ajuste linear: y = {m:.6f} x + {b:.6f}")

    except FileNotFoundError:
        print(f"Arquivo '{nome_arquivo}' não encontrado.")
    except ValueError:
        print("Formato de dado inválido. Cada linha deve ter dois números reais.")

if __name__ == '__main__':
    main()

Exercícios relacionados