Aquí
os dejo el código de un programa que ajusta rectas a una distribución lineal de
puntos.
Normalmente
las rectas que ajustaremos serán sobre datos experimentales, por lo que habrá
errores de medida de algún otro tipo. Por esta razón no encontraremos una recta
que pase por todos los puntos, sino que tendremos que encontrar una que se
aproxime a todos los puntos que encontramos con un error mínimo.
A
esto también se le llama mínimos cuadrados.
Estos
son los calculaos que hay que hacer:
Sean
los datos experimentales (x,y) ={ (2,5), (3,6), (1,4),(7,6),(5,8)}, se nos
plantea el siguiente sistema de ecuaciones:
B + 2M = 5
B + 3M = 6
B + 1M = 4
B + 7M = 6
B + 5M = 8
Donde
la M es la pendiente de nuestra recta y la B es la ordenada en el origen. Como
se ha explicado antes, no podremos encontrar una única solución , por lo que
deberemos aproximarla mediante mínimos cuadrados.
Para
ello primero escribiremos el sistema de manera matricial.
Para
hallar la recta de regresión, aplicamos la siguiente formula que es la de
mínimos cuadrados.
Que
si la resolvemos con sin los coeficientes, encontramos una expresión más
general de nuestro sistema, que al resolverlo ya si encontraremos la solución a
nuestro problema.
Este
último sistema de ecuaciones, es el que utiliza el programa para hayar las
rectas. La n es el numero de datos experimentales que tenemos.
Aquí
dejo los cálculos codificados en C, se entiende que ya se sabe programar en C,
y el código sólo está comentado.
#define
_CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
float sistema[2][3], *resultx, *resulty, pendiente = 0, ordenada = 0, sumax = 0, sumay = 0,sumax2 = 0,sumaxy = 0, aux=0;
/*
la matriz sistema la usaremos para
resolver el sistema de ecuaciones y y hallar la pendiente y ordenada en el
origen de nuestra recta
los punteros resultx y resulty los
usaremos para alamacenar los datos tomados experimentalmente en arrays
dinamicos
las variables pendiente y ordenada sera
donde se alojaran los resultados del sistema de ecuaciones
en las variables suma... se almacenaran
los distintos sumatorios que utilizaremos durnte los calculos
*/
int n=0, i=0,j=0;// estas variables seran
contadores durante nuestro programa
// do el
programa está metido dentro de un bucle do- while para preguntar al final a
usuario si quiere calcular mas rectas
do {
printf("Programa de regresion
lineal por metodo matricial\n");
printf("MUY IMPORTANTE, SI
INTRODUCES RESULTADOS EXPERIMENTALES IGUALES O REPETIDOS, EL RESULTADO SERA
ERRONEO\n");
// lo
primero de todo es preguntar al usuario por el numero de datos a introducir
para crea la memoria dinamica
printf("Introduzca cuantos
datos experimentales ha tomado\n");
scanf("%d", &n);
//despues
asignamos memoria a los arrays
resultx = (float *)malloc(n*sizeof(float));
if (resultx == NULL) {
printf("No hay
suficiente memoria\n");
system("pause");
return -1;
}
resulty = (float *)malloc(n*sizeof(float));
if (resulty == NULL) {
printf("No hay
suficiente memoria\n");
system("pause");
return 0
;
}
//tercero
recogemos los datos esperimentales mediante bucles for
for (i = 0; i < n; i++)
{
system("cls");
printf("Valor
experimental numero %d \n", i + 1);
printf("Introduzca
el valor del eje x\n");
scanf("%f", &resultx[i]);
printf("Introduzca
el valor del eje y\n");
scanf("%f", &resulty[i]);
system("cls");
}
//
calculamos los distintos sumatorios
//smatorio
x
for (i = 0;i < n;i++) {
sumax = sumax + resultx[i];
}
//
sumatorio y
for (i = 0;i < n;i++) {
sumay = sumay + resulty[i];
}
//sumatorio
xy
for (i = 0;i < n;i++) {
sumaxy = sumaxy + resultx[i] *
resulty[i];
}
//
sumatorio x2
for (i = 0;i < n;i++) {
sumax2 = sumax2 + resultx[i] *
resultx[i];
}
//metemos
los datos en la matriz del sistema
sistema[0][0] = n;
sistema[0][1] = sumax;
sistema[0][2] = sumay;
sistema[1][0] = sumax;
sistema[1][1] = sumax2;
sistema[1][2] = sumaxy;
// como
dejamos de utilizar lo arrays dinamicos los liberamos
free(resultx);
free(resulty);
//resolvemos
el sistema por el metodo de gaus-jordan
//primero
hacemos 1 el elemto 00
aux = sistema[0][0];
sistema[0][0] = sistema[0][0] / aux;
sistema[0][1] = sistema[0][1] / aux;
sistema[0][2] = sistema[0][2] / aux;
//segundo
hacemos 0 el elemtento 10
aux = sistema[1][0];
sistema[1][0] = sistema[1][0] - sistema[0][0] * aux;
sistema[1][1] = sistema[1][1] - sistema[0][1] * aux;
sistema[1][2] = sistema[1][2] - sistema[0][2] * aux;
//
despejamos la variable del elemento 11
pendiente = sistema[1][2] / sistema[1][1];
//despejamos
la ordenada en el orijen
ordenada = sistema[0][2] - sistema[0][1] * pendiente;
//muestra
el resultado por pantalla
printf("La recta resultante
es y = %.2f x + %.2f\n", pendiente,
ordenada);
printf("øDesea hacer otra
recta?\n");
printf("1. Si\n");
printf("2. No\n");
scanf("%d", &j);
system("cls");
} while (j==1);
system("pause");
return 0;
}
Si tenéis alguna duda, no dudéis en dejar un comentario o
escríbenos un mail a makersexperience@hotmail.com.
Síguenos en Twitter @makers_exp y entérate al instante de las
novedades del blog.