最小二乘法C语言的实现

来源:互联网 发布:淘宝收货可以延长多久 编辑:程序博客网 时间:2024/05/17 07:17

1.实验目的:

进一步熟悉曲线拟合的最小二乘法。

掌握编程语言字符处理程序的设计和调试技术。

 

2.实验要求:

输入:已知点的数目以及各点坐标 。

输出:根据最小二乘法原理以及各点坐标求出拟合曲线 。

 

3.程序流程:

(1)输入已知点的个数;

(2)分别输入已知点的X坐标;

(3)分别输入已知点的Y坐标;

(4)通过调用函数,求出拟合曲线。

 


最小二乘法原理如下:

根据一组给定的实验数据,求出自变量x与因变量y的函


4.难点,要根据已知坐标点求出多项式的系数。

5.程序流程图


6.源码(本程序已通过测试)


#include<stdio.h>#include<math.h>#define X 50#define Y 50float x[X],y[Y];int n;//输入的数据总组数即坐标的总个数void init();//初始化并输入相关数据void confrim();//确认输入的数据void deal();//根据输入的坐标点计算出拟合曲线void modify();//用于修改输错的相应坐标这样可以避免一些数据重新输入void main(){int select;system("color f1");//dos命令使界面变颜色init();//confrim();printf("请选择要拟合成几次多项式(提示:如果是一次函数就输入1二次函数就输入2):");scanf("%d",&select);//输入你要选择拟合的函数的次数deal(select);}void init()//初始化并输入相关数据{int i;printf ("\n*********************************************************\n");printf ("\n欢迎使用最小二乘法数据处理程序\n");printf ("\n请输入您要处理的数据的组数(提示:程序定义一对x,y值为一组数据):");while(1){scanf("%d",&n);if(n<=1){printf("\n理的数据的组数不能小于或等于1");printf ("\n请重新输入您要处理的数据的组数:");}else if(n>50){printf ("\n对不起,本程序暂时无法处理50组以上的数据");printf ("\n请重新输入您要处理的数据的组数:");} else break;}for (i=0;i<n;i++)//输入相应坐标点将其存到数组里{printf ("\n请输入第%d个x的值x%d=",i+1,i+1);scanf ("%f",&x[i]);printf ("\n请输入对应的y的值:y%d=",i+1);scanf ("%f",&y[i]);}system("color f2");//system("cls");//清屏}void deal(int select)//采用克莱默法则求解方程{int i;float a0,a1,a2,temp,temp0,temp1,temp2;float sy=0,sx=0,sxx=0,syy=0,sxy=0,sxxy=0,sxxx=0,sxxxx=0;//定义相关变量for(i=0;i<n;i++){sx+=x[i];//计算xi的和sy+=y[i];//计算yi的和sxx+=x[i]*x[i];//计算xi的平方的和sxxx+=pow(x[i],3);//计算xi的立方的和sxxxx+=pow(x[i],4);//计算xi的4次方的和sxy+=x[i]*y[i];//计算xi乘yi的的和sxxy+=x[i]*x[i]*y[i];//计算xi平方乘yi的和}temp=n*sxx-sx*sx;//方程的系数行列式temp0=sy*sxx-sx*sxy;temp1=n*sxy-sy*sx;a0=temp0/temp;a1=temp1/temp;if(select==1){printf("经最小二乘法拟合得到的一元线性方程为:\n"); printf("f(x)=%3.3fx+%3.3f\n",a1,a0); system("pause");}temp=n*(sxx*sxxxx-sxxx*sxxx)-sx*(sx*sxxxx-sxx*sxxx)//方程的系数行列式+sxx*(sx*sxxx-sxx*sxx);temp0=sy*(sxx*sxxxx-sxxx*sxxx)-sxy*(sx*sxxxx-sxx*sxxx)+sxxy*(sx*sxxx-sxx*sxx);temp1=n*(sxy*sxxxx-sxxy*sxxx)-sx*(sy*sxxxx-sxx*sxxy)+sxx*(sy*sxxx-sxy*sxx);temp2=n*(sxx*sxxy-sxy*sxxx)-sx*(sx*sxxy-sy*sxxx)+sxx*(sx*sxy-sy*sxx);a0=temp0/temp;a1=temp1/temp;a2=temp2/temp;if(select==2){printf("经最小二乘法拟合得到的二次近似方程为:\n"); printf("f(x)=%3.3fx2+%3.3fx+%3.3f\n",a2,a1,a0); system("pause");}}void modify()//修改输错的相应坐标{  int z;char flag;while(1){printf("请输入你要修改的是第几组数据:");scanf("%d",&z);printf ("\n请输入你要修改的第%d个x的值x%d=",z,z);scanf ("%f",&x[z-1]);printf ("\n请输入你要修改的对应的y的值:y%d=",z);scanf ("%f",&y[z-1]);printf("是否继续修改数据是Y否N:");getchar();scanf("%c",&flag);if(flag=='N'||flag=='n')break;}system("cls");//清屏confrim();}void confrim(){char flag;int i;while(1){for(i=0;i<n;i++){printf ("请输入第%d个x的值x%d=",i+1,i+1);printf ("%f",x[i]);printf ("  输入对应的y的值:y%d=",i+1);printf("%f",y[i]);printf("\n");}printf("确认你输入的数据是Y否N(即重新输入)修改M:");getchar();scanf("%c",&flag);if(flag=='y'||flag=='Y')break;else if(flag=='n'||flag=='N')init();else {modify();break;}}}

测试

1拟合二次曲线结果(书上的)


2.拟合一次曲线结果




0 0
原创粉丝点击