/******************************
 *                            *
 * MAC-115              EP #2 *
 * Prof. Carlos Eduardo       *
 *                            *
 * Félix Almeida - 27/04/2000 *
 *                            *
 ******************************/

/*

  Este programa calcula, através do método dos mínimos quadrados, uma reta
que melhor aproxima um conjunto de pontos dados.

*/

#include <stdio.h>
#include <math.h>

#define TAM_NOME 100 /* Tamanho máximo do nome do arquivo que contém as
                        coordenadas dos pontos. */

int main(void) {
	FILE *arqentrada;
	char nome[TAM_NOME];
	double x, y, m, b;

	int n = 0;
	double soma_x, soma_y, soma_x2, soma_xy, denominador;
	/* arqentrada : apontador para o arq. que contém as coord. dos pontos.
	   nome       : guarda o nome do arq. que contém as coord. dos pontos.
	   x          : recebe o valor das abscissas dos pontos lidos do arq.
	   y          : recebe o valor das ordenadas dos pontos lidos do arq.
	   m          : guarda o coeficiente angular da reta de aproximação.
	   b          : guarda o coeficiente linear da reta de aproximação.
	   n          : contador que guarda o número de pontos lidos do arquivo.
	   soma_x     : guarda o valor da soma de todas as abscissas.
	   soma_y     : guarda o valor da soma de todas as ordenadas.
	   soma_x2    : guarda o valor da soma de todos os quad. das abscissas.
	   soma_xy    : guarda o valor da soma do prod. de cada abscissa pela
	                sua ordenada.
	   denominador: guarda o valor do denominador usado nos cálculos dos
	                coeficientes linear (b) e angular (m).
	*/

	soma_x = soma_y = soma_x2 = soma_xy = 0;

	printf("\n\nAproximacao de uma reta pelo metodo dos minimos quadrados\n\n");
	printf("Entre com o nome do arquivo de dados: ");
	scanf("%s", nome);

	/* Verifica se o arquivo fornecido realmente existe. */
	if ((arqentrada = fopen(nome, "r")) == NULL) {
		printf("Arquivo %s nao foi encontrado\n\n", nome);
		return 1;
	}

	/* Laço responsável pela leitura das coordenadas dos pontos do arquivo e
	   pelo cálculo das somas das coordenadas. */
	while (!feof(arqentrada)) {
		fscanf(arqentrada, "%lf %lf ", &x, &y);
		n++;
		printf("x%d = %7.3f y%d = %7.3f\n", n, x, n, y);
		soma_x += x;
		soma_y += y;
		soma_x2 += pow(x, 2);
		soma_xy += x * y;
	}

	/* Mostra, na forma matricial, o sistema para o cálculo dos coeficientes
	   linear (b) e angular (m). */
	printf("\n\n[%7.3f  %7.3f] b = [%7.3f]\n", (double) n, soma_x, soma_y);
	printf("[%7.3f  %7.3f] m = [%7.3f]\n\n", soma_x, soma_x2, soma_xy);

	/* Cálculo dos coeficientes linear (b) e angular (m) através da regra
	   de Cramer. */
	denominador = n * soma_x2 - pow(soma_x, 2);
	printf("denominador = %7.3f.\n\n", denominador);
	b = (soma_y * soma_x2 - soma_x * soma_xy) / denominador;
	m = (n * soma_xy - soma_x * soma_y) / denominador;

	printf("A equacao da reta e' y = (%7.3f) x + (%7.3f).\n\n\n", m, b);

	fclose(arqentrada);
	return 0;
}

