C++最小二乘法? 最小二乘法c语言程序
怎么用C语言实现最小二乘法?
最小二乘法常用于根据实测数据求线性方程的最近似解。根据如图(图片引用于百度百科)的描述,利用C语言求,使用最小二乘法算法求线性方程的解,程序如下:
#include <stdio.h>
#define N 4 //共有4个记录,根据需要增加记录
typedef struct Data{ //定义实验记录结构
int w; //实验次数
double x;
double y;
}DATA;
//根据d中的n个DATA记录,计算出线性方程的a,b两值
void getcs(DATA *d,int n,double &a,double &b){
double fi11=0,fi12=0,fi21=0,fi22=0,f1=0,f2=0;
int i;
for(i=0;i<n;i++){
fi11+=d[i].w;
fi12+=d[i].w*d[i].x;
fi21=fi12;
fi22+=d[i].w*d[i].x*d[i].x;
f1+=d[i].w*d[i].y;
f2+=d[i].w*d[i].x*d[i].y;
}
//解一元一次方程
b=(f2*fi11/fi21-f1)/(fi22*fi11/fi21-fi12);
a=(f2*fi12/fi22-f1)/(fi21*fi12/fi22-fi11);
}
int main(){
DATA d[N]={ //定义时赋初值,共4个记录
{2,0.1,1.1},
{1,0.2,1.9},
{1,0.3,3.1},
{1,0.4,3.9}
};
double a,b;
getcs(d,N,a,b); //计算线性方程参数a,b
printf("线性方程是:Y=%.4lf+%.4lfX\n",a,b);
}
最小二乘法公式
最小二乘法公式是一个数学的公式,最小二乘法通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。
公式写法:
a=(NΣxy-ΣxΣy)/(NΣx^2-(Σx)^2)
b=y(平均)-a*x(平均)
最小二乘法C语言程序怎么编?
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#include "math.h"
#define N 9//N个节点
#define M 2//M次拟合
#define K 2*M
void zhuyuan (int k,int n,float a[M+1][M+2])
{int t,i,j;
float x,y;
x=fabs(a[k][k]);t=k;
for (i=k+1;i<=n;i++)
if (fabs(a[i][k])>x)
{x=fabs(a[i][k]);t=i;}
for (j=k;j<=n+1;j++)
{y=a[k][j];a[k][j]=a[t][j];a[t][j]=y;}
}
void xiaoyuan(int n,float a[M+1][M+2])
{int k,i,j;
for(i=0;i<n;i++)
{zhuyuan(i,n,a);
for (j=i+1;j<=n;j++)
for (k=i+1;k<=n+1;k++)
a[j][k]=a[j][k]-a[j][i]*a[i][k]/a[i][i];
}
}
void huidai(int n,float a[M+1][M+2],float x[M+1])
{int i,j;
x[n]=a[n][n+1]/a[n][n];
for (i=n-1;i>=0;i--)
{ x[i]=a[i][n+1];
for (j=i+1;j<=n;j++)
x[i]=x[i]-a[i][j]*x[j];
x[i]=x[i]/a[i][i];
}
}
void main()
{float x_y[N][2],A[N][K+1],B[N][M+1],AA[K+1],BB[M+1],a[M+1][M+2],m[M+1];
int i,j,n;
printf("请输入%d个已知点:\n",N);
for(i=0;i<N;i++)
{
printf("(x%d y%d):",i,i);
scanf("%f %f",&x_y[i][0],&x_y[i][1]);
}
for(i=0;i<N;i++)
{
A[i][0]=1;
for(j=1;j<=K;j++)
A[i][j]=A[i][j-1]*x_y[i][0];
for(j=0;j<=M;j++)
B[i][j]=A[i][j]*x_y[i][1];
}
for(j=0;j<=K;j++)
for(AA[j]=0,i=0;i<N;i++)
AA[j]+=A[i][j];
for(j=0;j<=M;j++)
for(BB[j]=0,i=0;i<N;i++)
BB[j]+=B[i][j];
for(i=0;i<M+1;i++)
{a[i][M+1]=BB[i];
for(j=0;j<=M;j++)
a[i][j]=AA[i+j];}
n=M;
printf("正规系数矩阵为:\n");
for(i=0;i<=n;i++)
{for(j=0;j<=n+1;j++)
printf("%f ",a[i][j]);
printf("\n");}
xiaoyuan(n,a);
huidai(n,a,m);
printf("拟合曲线方程为:\ny(x)=%g",m[0]);
for(i=1;i<=n;i++)
{
printf(" + %g",m[i]);
for(j=0;j<i;j++)
{
printf("*X");
}
}
}
最小二乘法怎么用?
LINEST 函数可通过使用最小二乘法计算与现有数据最佳拟合的直线,来计算某直线的统计值,然后返回描述此直线的数组。也可以将 LINEST 与其他函数结合使用来计算未知参数中其他类型的线性模型的统计值,包括多项式、对数、指数和幂级数。因为此函数返回数值数组,所以必须以数组公式的形式输入。请按照本文中的示例使用此函数。
直线的公式为:
y = mx + b
- 或 -
y = m1x1 + m2x2 + ... + b(如果有多个区域的 x 值)
其中,因变量 y 是自变量 x 的函数值。m 值是与每个 x 值相对应的系数,b 为常量。注意,y、x 和 m 可以是向量。LINEST 函数返回的数组为 {mn,mn-1,...,m1,b}。LINEST 函数还可返回附加回归统计值。
语法
LINEST(known_y's, [known_x's], [const], [stats])LINEST 函数语法具有以下参数 (参数:为操作、事件、方法、属性、函数或过程提供信息的值。):
Known_y's 必需。关系表达式 y = mx + b 中已知的 y 值集合。
如果 known_y's 对应的单元格区域在单独一列中,则 known_x's 的每一列被视为一个独立的变量。
如果 known_y's 对应的单元格区域在单独一行中,则 known_x's 的每一行被视为一个独立的变量。
Known_x's 可选。关系表达式 y = mx + b 中已知的 x 值集合。
known_x's 对应的单元格区域可以包含一组或多组变量。如果仅使用一个变量,那么只要 known_y's 和 known_x's 具有相同的维数,则它们可以是任何形状的区域。如果使用多个变量,则 known_y's 必须为向量(即必须为一行或一列)。
如果省略 known_x's,则假设该数组为 {1,2,3,...},其大小与 known_y's 相同。
const 可选。一个逻辑值,用于指定是否将常量 b 强制设为 0。
如果 const 为 TRUE 或被省略,b 将按通常方式计算。
如果 const 为 FALSE,b 将被设为 0,并同时调整 m 值使 y = mx。
stats 可选。一个逻辑值,用于指定是否返回附加回归统计值。
如果 stats 为 TRUE,则 LINEST 函数返回附加回归统计值,这时返回的数组为 {mn,mn-1,...,m1,b;sen,sen-1,...,se1,seb;r2,sey;F,df;ssreg,ssresid}。
如果 stats 为 FALSE 或被省略,LINEST 函数只返回系数 m 和常量 b。