最小二乘法直线拟合C程序
NET与Matlab结合——最小二乘法直线拟合(C#)

NET与Matlab结合——最⼩⼆乘法直线拟合(C#)NET与Matlab结合 —— 最⼩⼆乘法直线拟合(C#)⾸先是⼀个.m⽂件drawgraph.m,确保它能够在Matlab⾥运⾏。
我这⾥是最⼩⼆乘法直线拟合程序。
%最⼩⼆乘法直线拟合%Created by Safirst C. Ke 2007.8.29 Wed 14:51function drawgraph(coords)%传⼊的参数为两⾏向量,第⼀⾏为x坐标,第⼆⾏为坐标。
%axis ([0 100 0 100]);grid on;hold on;%显⽰欲拟合的点的位置plot(coords(1,:), coords(2,:), '*');%分解x,y坐标x = coords(1,:)y = coords(2,:)'b = size(coords);c = ones(1, b(2));MT = [c; x];M = MT';%f为直线函数,f = mx + b;f = inv(MT * M) * MT * y['y = ', num2str(f(2)), 'x + ', num2str(f(1))]%显⽰最终拟合的直线x = -max(x):max(x);y = f(1) + f(2) * x;plot(x, y);xlabel('X轴');ylabel('Y轴');title('最⼩⼆乘法直线拟合 by Safirst C. Ke');legend(['y = ', num2str(f(2)), 'x + ', num2str(f(1))]);然后将这个⽂件包含在.NET的类库⼯程中,并进⾏编译。
这⾥需要理解它的过程,毕竟.NET不能编译.m⽂件。
怎么做到的呢?通过设置这个⼯程的⽣成事件属性,添加为call PlotDemoBuild.bat然后在PlotDemoBuild.bat这个⽂件⾥⾯写好⽤Matlab编译器mcc编译的命令⾏,最重要的部分就是mcc -M -silentsetup -vg -B "dotnet:PlotDemoComp,Plotter,2.0,private" -d ../../src ../../drawgraph.m这样的话,点击⽣成,就会通过mcc产⽣dll,即我们需要的类库。
最小二乘法曲线拟合C语言实现

最小二乘法曲线拟合C语言实现简单思路如下:1,采用目标函数对多项式系数求偏导,得到最优值条件,组成一个方程组;2,方程组的解法采用行列式变换(两次变换:普通行列式——三角行列式——对角行列式——求解),行列式的求解算法上优化过一次了,目前还没有更好的思路再优化运算方法,限幅和精度准备再修改修改目前存在的问题:1,代码还是太粗糙2,数学原理可行,但是计算机运算有幅度溢出和精度问题,这方面欠考虑,导致高阶大数据可能拟合失败下面附简单注释版代码:#include "stdafx.h"#include "stdlib.h"#include "math.h"//把二维的数组与一维数组的转换,也可以直接用二维数组,只是我的习惯是不用二维数组#define ParaBuffer(Buffer,Row,Col) (*(Buffer + (Row) * (SizeSrc + 1) + (Col)))///************************************************************** *********************从txt文件里读取double型的X,Y数据txt文件里的存储格式为X1 Y1X2 Y2X3 Y3X4 Y4X5 Y5X6 Y6X7 Y7X8 Y8函数返回X,Y,以及数据的数目(以组为单位)*************************************************************** ********************/static int GetXY(const char* FileName, double* X, double* Y, int* Amount){FILE* File = fopen(FileName, "r");if (!File)return -1;for (*Amount = 0; !feof(File); X++, Y++, (*Amount)++)if (2 != fscanf(File, (const char*)"%lf %lf", X, Y))break;fclose(File);return 0;}/************************************************************** *********************打印系数矩阵,只用于调试,不具备运算功能对于一个N阶拟合,它的系数矩阵大小是(N + 1)行(N + 2)列double* Para:系数矩阵存储地址int SizeSrc:系数矩阵大小(SizeSrc)行(SizeSrc + 1)列***********************************************************************************/static int PrintPara(double* Para, int SizeSrc){int i, j;for (i = 0; i < SizeSrc; i++){for (j = 0; j <= SizeSrc; j++)printf("%10.6lf ", ParaBuffer(Para, i, j));printf("\r\n");}printf("\r\n");return 0;}/************************************************************** *********************系数矩阵的限幅处理,防止它溢出,目前这个函数很不完善,并不能很好地解决这个问题原理:矩阵解行列式,同一行乘以一个系数,行列式的解不变当然,相对溢出问题,还有一个精度问题,也是同样的思路,现在对于这两块的处理很不完善,有待优化以行为单位处理*************************************************************** ********************/static int ParalimitRow(double* Para, int SizeSrc, int Row){int i;double Max, Min, Temp;for (Max = abs(ParaBuffer(Para, Row, 0)), Min = Max, i = SizeSrc; i; i--){Temp = abs(ParaBuffer(Para, Row, i));if (Max < Temp)Max = Temp;if (Min > Temp)Min = Temp;}Max = (Max + Min) * 0.000005;for (i = SizeSrc; i >= 0; i--)ParaBuffer(Para, Row, i) /= Max;return 0;}/************************************************************** *********************同上,以矩阵为单位处理*************************************************************** ********************/static int Paralimit(double* Para, int SizeSrc){int i;for (i = 0; i < SizeSrc; i++)if (ParalimitRow(Para, SizeSrc, i))return -1;return 0;}/************************************************************** *********************系数矩阵行列式变换*************************************************************** ********************/static int ParaPreDealA(double* Para, int SizeSrc, int Size){int i, j;for (Size -= 1, i = 0; i < Size; i++){for (j = 0; j < Size; j++)ParaBuffer(Para, i, j) = ParaBuffer(Para, i, j) * ParaBuffer(Para, Size, Size) - ParaBuffer(Para, Size, j) * ParaBuffer(Para, i, Size);ParaBuffer(Para, i, SizeSrc) = ParaBuffer(Para, i, SizeSrc) * ParaBuffer(Para, Size, Size) - ParaBuffer(Para, Size, SizeSrc) * ParaBuffer(Para, i, Size);ParaBuffer(Para, i, Size) = 0;ParalimitRow(Para, SizeSrc, i);}return 0;}/************************************************************** *********************系数矩阵行列式变换,与ParaPreDealA配合完成第一次变换,变换成三角矩阵*************************************************************** ********************/static int ParaDealA(double* Para, int SizeSrc){int i;for (i = SizeSrc; i; i--)if (ParaPreDealA(Para, SizeSrc, i))return -1;return 0;}/************************************************************** *********************系数矩阵行列式变换*************************************************************** ********************/static int ParaPreDealB(double* Para, int SizeSrc, int OffSet) {int i, j;for (i = OffSet + 1; i < SizeSrc; i++){for (j = OffSet + 1; j <= i; j++)ParaBuffer(Para, i, j) *= ParaBuffer(Para, OffSet, OffSet);ParaBuffer(Para, i, SizeSrc) = ParaBuffer(Para, i, SizeSrc) * ParaBuffer(Para, OffSet, OffSet) - ParaBuffer(Para, i, OffSet) * ParaBuffer(Para, OffSet, SizeSrc);ParaBuffer(Para, i, OffSet) = 0;ParalimitRow(Para, SizeSrc, i);}return 0;}/************************************************************** *********************系数矩阵行列式变换,与ParaPreDealB配合完成第一次变换,变换成对角矩阵,变换完毕***********************************************************************************/static int ParaDealB(double* Para, int SizeSrc){int i;for (i = 0; i < SizeSrc; i++)if (ParaPreDealB(Para, SizeSrc, i))return -1;for (i = 0; i < SizeSrc; i++){if (ParaBuffer(Para, i, i)){ParaBuffer(Para, i, SizeSrc) /= ParaBuffer(Para, i, i);ParaBuffer(Para, i, i) = 1.0;}}return 0;}/************************************************************** *********************系数矩阵变换*************************************************************** ********************/static int ParaDeal(double* Para, int SizeSrc){PrintPara(Para, SizeSrc);Paralimit(Para, SizeSrc);PrintPara(Para, SizeSrc);if (ParaDealA(Para, SizeSrc))return -1;PrintPara(Para, SizeSrc);if (ParaDealB(Para, SizeSrc))return -1;return 0;}/************************************************************** *********************最小二乘法的第一步就是从XY数据里面获取系数矩阵double* Para:系数矩阵地址const double* X:X数据地址const double* Y:Y数据地址int Amount:XY数据组数int SizeSrc:系数矩阵大小(SizeSrc)行(SizeSrc + 1)列*************************************************************** ********************/static int GetParaBuffer(double* Para, const double* X, const double* Y, int Amount, int SizeSrc){int i, j;for (i = 0; i < SizeSrc; i++)for (ParaBuffer(Para, 0, i) = 0, j = 0; j < Amount; j++)ParaBuffer(Para, 0, i) += pow(*(X + j), 2 * (SizeSrc - 1) - i);for (i = 1; i < SizeSrc; i++)for (ParaBuffer(Para, i, SizeSrc - 1) = 0, j = 0; j < Amount; j++) ParaBuffer(Para, i, SizeSrc - 1) += pow(*(X + j), SizeSrc - 1 - i);for (i = 0; i < SizeSrc; i++)for (ParaBuffer(Para, i, SizeSrc) = 0, j = 0; j < Amount; j++)ParaBuffer(Para, i, SizeSrc) += (*(Y + j)) * pow(*(X + j), SizeSrc - 1 - i);for (i = 1; i < SizeSrc; i++)for (j = 0; j < SizeSrc - 1; j++)ParaBuffer(Para, i, j) = ParaBuffer(Para, i - 1, j + 1);return 0;}/************************************************************** *********************整个计算过程*************************************************************** ********************/int Cal(const double* BufferX, const double* BufferY, int Amount, int SizeSrc, double* ParaResK){double* ParaK = (double*)malloc(SizeSrc * (SizeSrc + 1) * sizeof(double));GetParaBuffer(ParaK, BufferX, BufferY, Amount, SizeSrc);ParaDeal(ParaK, SizeSrc);for (Amount = 0; Amount < SizeSrc; Amount++, ParaResK++) *ParaResK = ParaBuffer(ParaK, Amount, SizeSrc);free(ParaK);return 0;}/************************************************************** *********************测试main函数数据组数:20阶数:5***********************************************************************************/int main(int argc, char* argv[]){//数据组数int Amount;//XY缓存,系数矩阵缓存double BufferX[1024], BufferY[1024], ParaK[6];if (GetXY((const char*)"test.txt", (double*)BufferX, (double*)BufferY, &Amount))return 0;//运算Cal((const double*)BufferX, (const double*)BufferY, Amount, sizeof(ParaK) / sizeof(double), (double*)ParaK);//输出系数for (Amount = 0; Amount < sizeof(ParaK) / sizeof(double); Amount++)printf("ParaK[%d] = %lf!\r\n", Amount, ParaK[Amount]);//屏幕暂留system("pause");return 0;}。
最小二乘法c语言实现

最小二乘法c语言实现最小二乘法是一种经典的数据拟合方法,它可以用于求解线性回归问题。
在实际应用中,我们经常需要使用最小二乘法来对一些数据进行拟合,从而得到一个最佳的线性模型。
C语言是一种高效、灵活的编程语言,非常适合进行科学计算和数据处理。
在本文中,我们将介绍如何使用C语言实现最小二乘法,并且给出一个简单的示例程序。
首先,我们需要明确最小二乘法的原理。
其核心思想是寻找一个最佳的线性函数,使得该函数与给定的数据点之间的误差最小。
具体来说,我们可以定义误差函数为:E = Σ(yi - a - bx_i)^2其中,a和b是待求的系数,xi和yi代表第i个数据点的横纵坐标。
我们的目标是寻找a和b的取值,使得E最小。
为了求解这个问题,我们可以采用求导的方法来求得a和b的解析式。
具体来说,我们可以对E关于a和b分别求导,并令其为0,得到如下方程组:Σyi = na + bΣxiΣxiyi = aΣxi + bΣ(x_i)^2其中,n为数据点的数量。
通过解这个方程组,我们可以得到a 和b的解析式:a = (ΣyiΣ(x_i)^2 - ΣxiyiΣxi) / (nΣ(x_i)^2 - (Σxi)^2)b = (nΣxiyi - ΣxiΣyi) / (nΣ(x_i)^2 - (Σxi)^2)有了这个解析式,我们就可以使用C语言来实现最小二乘法。
下面是一个简单的示例程序:#include <stdio.h>int main(){int n = 5; // 数据点的数量double xi[] = {1, 2, 3, 4, 5}; // 横坐标double yi[] = {2.1, 3.9, 6.1, 8.2, 10.2}; // 纵坐标double sum_xi = 0, sum_yi = 0, sum_xi2 = 0, sum_xiyi = 0; for (int i = 0; i < n; i++) {sum_xi += xi[i];sum_yi += yi[i];sum_xi2 += xi[i] * xi[i];sum_xiyi += xi[i] * yi[i];}double a = (sum_yi * sum_xi2 - sum_xi * sum_xiyi) / (n * sum_xi2 - sum_xi * sum_xi);double b = (n * sum_xiyi - sum_xi * sum_yi) / (n * sum_xi2 - sum_xi * sum_xi);printf('a = %.2f, b = %.2f', a, b);return 0;}在这个程序中,我们假设有5个数据点,分别对应横坐标1到5,纵坐标2.1到10.2。
最小二乘法-曲线拟合—C语言程序

for(i=0;i<=m;i++)
s[i][m+1]=t[i][0];
for(i=0;i<=m;i++)
{
for(j=0;j<=m+1;j++)
printf("%f\t",s[i][j]);
printf("\n");
}
ColPivot(s,m+1,t,x);
printf("\n\n");
for(i=0;i<=m;i++)
}
}
}
for(i=n-1;i>=0;i--)
{
for(j=n-1;j>=i+1;j--)
b[i][0]=b[i][0]-a[i][j]*x[j];
x[i]=b[i][0]/a[i][i];
}
}
void main()
{
float x[99],y[99],z[99],s[99][99],t[99][1];
for(j=k;j<n;j++)
{
temp=a[I][பைடு நூலகம்]; a[I][j]=a[k][j]; a[k][j]=temp;
}
}
for(i=k+1;i<n;i++)
{
m=a[i][k]/a[k][k];
b[i][0]=b[i][0]-b[k][0]*m;
for(j=0;j<n;j++)
a[i][j]=a[i][j]-a[k][j]*m;
printf("\na[%d]=%f",i,x[i]);
最小二乘法 c语言

最小二乘法 c语言最小二乘法是一种常用的数学方法,用于通过已知数据点拟合出一条最佳拟合曲线。
在本文中,我们将讨论如何使用C语言实现最小二乘法。
我们需要明确最小二乘法的基本原理。
最小二乘法的目标是找到一条曲线,使得该曲线上的点到已知数据点的距离之和最小。
具体地,我们假设已知数据点的集合为{(x1, y1), (x2, y2), ..., (xn, yn)},我们需要找到一条曲线y = f(x),使得f(xi)与yi的差的平方和最小。
那么,如何在C语言中实现最小二乘法呢?首先,我们需要定义一个函数来计算拟合曲线上的点f(xi)。
在这个函数中,我们可以使用多项式的形式来表示拟合曲线。
例如,我们可以选择使用一次多项式y = ax + b来拟合数据。
然后,我们可以使用最小二乘法的公式来计算出最优的a和b的值。
接下来,我们需要编写一个函数来计算拟合曲线上每个点f(xi)与已知数据点yi的差的平方和。
通过遍历已知数据点的集合,并计算每个点的差的平方,最后将所有差的平方求和,即可得到拟合曲线的误差。
然后,我们可以使用梯度下降法来最小化误差函数。
梯度下降法是一种优化算法,通过不断迭代来找到误差函数的最小值。
在每次迭代中,我们通过计算误差函数对参数a和b的偏导数,来更新a和b的值。
通过多次迭代,最终可以找到最优的a和b的值,从而得到最佳拟合曲线。
我们可以编写一个主函数来调用以上的函数,并将最终的拟合曲线绘制出来。
在这个主函数中,我们可以读取已知数据点的集合,并调用最小二乘法函数来计算拟合曲线的参数。
然后,我们可以使用绘图库来绘制已知数据点和拟合曲线,并将结果输出到屏幕上。
通过以上的步骤,我们就可以使用C语言实现最小二乘法了。
当然,在实际应用中,我们可能会遇到更复杂的数据和更高阶的多项式拟合。
但是基本的原理和方法是相同的,只是需要做一些适当的调整。
总结一下,最小二乘法是一种常用的数学方法,用于通过已知数据点拟合出一条最佳拟合曲线。
c语言 最小二乘法

c语言最小二乘法
C语言中的最小二乘法是一种常用的统计学工具,用于拟合一组数据的最佳直线。
它的原理是通过对这组数据进行线性回归,找到最能代表这组数据的一条直线,从而求出直线的斜率和截距,并计算出最小二乘法的误差平方和。
在C语言中,可以通过利用数组和循环语句来实现最小二乘法的计算,具有简单易学、方便快捷等优点。
一般来说,使用最小二乘法能够更准确地预测未知数据的趋势,并为数据的分析和应用提供依据。
- 1 -。
c语言最小二乘法拟合直线

c语言最小二乘法拟合直线最小二乘法是一种拟合直线或曲线的方法,适用于给定一组实验数据的情况。
在C语言中,可以使用以下步骤实现最小二乘法拟合直线:1. 定义并初始化数据变量。
例如:double x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double y[10] = {2.5,3.7,4.1, 4.8,5.5,6.3,7.2,8.4, 8.5,9.1};2. 求出数据变量的平均值。
例如:double sumx = 0, sumy = 0, avgx, avgy; for(int i=0; i<10; i++) { sumx += x[i]; sumy +=y[i]; } avgx = sumx / 10; avgy = sumy / 10;3. 求出数据变量的协方差和方差。
例如:double s_xx = 0,s_xy = 0, s_yy = 0; for(int i=0; i<10; i++) { s_xx += (x[i] - avgx) * (x[i] - avgx); s_xy += (x[i] - avgx) * (y[i] - avgy); s_yy += (y[i] - avgy) * (y[i] - avgy); }4. 求出拟合直线的斜率和截距。
例如:double slope = s_xy / s_xx; double intercept = avgy - slope * avgx;5. 输出结果。
例如:printf("拟合直线方程为 y = %.2fx+ %.2f", slope, intercept);通过以上步骤,就可以使用最小二乘法拟合给定数据的直线。
最小二乘法直线拟合 用VC实现的

D2=D2+Q*Q;
C=Y[i]*Q+C;
G=(X[i]-Z)*Q*Q+G;
}
C=C/D2;
P=G/D2;
Q=D2/D1;
D1=D2;
A[j]=C*S[j];
T[j]=S[j];
for(jk=j-1;jk>=1;jk--)
long lCount=m_FoldList->GetCount();
if(lCount<2)return FALSE;
CFoldPoint *pFold;
double mX,mY,mXX,mXY,n;
mX=mY=mXX=mXY=0;
n=lCount;
POSITION pos=m_FoldList->GetHeadPosition();
for(i=1;i<=N;i++)
{
P=P+(X[i]-Z);
C=C+Y[i];
}
C=C/D1;
P=P/D1;
A[1]=C*B[1];
if(M>1)
{
T[2]=1.0;
T[1]=-P;
D2=0.0;
C=0.0;
G=0.0;
{
// X[] Y[] 使需要拟合的点,A[]时拟合曲线的系数,
double S[21],T[21],B[21];
double Z,D1,P,C,D2,G,Q,DT;
int i,j,jk;
for(i=1;i<=M;i++)// DO 5 i=1,M
{
A[i]=0.0;