求大神帮我改改这个程序 设置可变动大小的数组(大概是关于动态内存分配吧)
这个是个最小二乘法拟合的程序,通过读取TXT文件里的点坐标来拟合。因为我设数组什么的只会最基本的方法,所以这里很死板地只能拟合11个点
听说这个跟动态内存分布有关 但是对于这个我完全不会
求大神帮我修改成可以拟合任意个点的程序 多谢
更详细的东西在程序中间有一大段注释
0 0
5 1.27
10 2.16
15 2.86
20 3.44
25 3.87
30 4.15
35 4.37
40 4.51
45 4.58
50 4.02
以上为原始的shuru.txt内容,11个点。
#include "StdAfx.h"
#include<fstream>
#include<math.h>
#include <iomanip>
using namespace std;
double maxB(double array[4]);
double gt(double x[11],double y[11]);
double GS(double a[4][4],double b[4],double e[],double s[], double x[4]/*多项式系数*/);
int CalculateMinBin(const char *pFilename, double result[4])//因为这个是从直接从MFC里面提出来的 要单独运行的版本我在最后附上
{
if(!pFilename)
return -1;
double a[11]={1,1,1,1,1,1,1,1,1,1,1},b[11],c[11],d[11],e[11],f[10],g[4];
int i;
ifstream fin(pFilename);
if (!fin)
return 1;
for(i=0;i<11;i++)//读入n个数据点
{
fin>>b[i];fin>>e[i];//左列写入x,右列写入y
c[i]=b[i]*b[i];//x平方
d[i]=b[i]*b[i]*b[i];//x立方
}
fin.close();//结束输入
f[0]=gt(a,a);f[1]=gt(a,b);f[2]=gt(a,c);f[3]=gt(a,d);f[4]=gt(b,b);f[5]=gt(b,c);f[6]=gt(b,d);
f[7]=gt(c,c);f[8]=gt(c,d);f[9]=gt(d,d);g[0]=gt(a,e);g[1]=gt(b,e);g[2]=gt(c,e);g[3]=gt(d,e);
double array[4][4]={{f[0],f[1],f[2],f[3]},{f[1],f[4],f[5],f[6]},{f[2],f[5],f[7],f[8]},{f[3],f[6],f[8],f[9]}};//生成4*4矩阵
return GS(array,g,e,b, result);
/*
f[i]
0 1 2 3
1 4 5 6
2 5 7 8
3 6 8 9
array[4][4] g[i] e[i] b[i] a b c d e
aa ab ac ad ae y1 x1
ab bb bc bd be y2 x2
ac bc cc cd ce y3 x3 1 x x平方 x立方 y
ad bd cd dd de y4 x4
array[4][4] g[i] e[i] b[i] a b c d e
正定矩阵 右侧矩阵 y值 x值
关系: 正定矩阵 *多项式系数矩阵=x^n*y 0加到m n=0-3四次 m=0-10十一项
array[4][4]* x[i] = g[i]
1 x x^2 x^3 a0 y
x x^2 x^3 x^4 a1 y*x
x^2 x^3 x^4 x^5 a2 y*x^2
x^3 x^4 x^5 x^6 a3 y*x^3
x^n为11个x的n次方之和 多项式系数 y*x^n为11个y*x^n的和 y x
GS( double a[4][4], double b[4], double e[11], double s[11])
解线性方程组。
主对角线优势,使用高斯-赛德尔迭代法求解x[i]
此处拟合算法可以通用,与原始数据点的个数无关。
a[]包含相当于坐标点数量的1,比如a[11]由11个1组成
f[10]包含正定矩阵所有元素,不用改变。
g[4]包含所有右侧矩阵元素,不用改变
要改的地方就是本CPP里所有写着11以及与11有关联的地方
比如所有的?[11]以及各种for(?<11)及相关等
因为希望能读取任意组坐标,所以将11变为可以根据shuru.txt中坐标数量来取值的数。
比如这里都取11,因为shuru.txt里有11个点的坐标。
如果shuru.txt里有12个点坐标,把所有11改成12即可。
但是手动改起来太麻烦,所以想个办法能让他们根据点坐标数量自动取值。
比如shuru.txt里包含有n个点,则自动变为?[n]与for(?<n)
貌似是要使用动态内存分配的方法?
*/
}
double gt(double x[11],double y[11])
{
double sum=0;
for(int i=0;i<11;i++)
sum=x[i]*y[i]+sum;
return sum;
}//定义gt,累加之和。
double GS(double a[4][4],double b[4],double e[11],double s[11], double x[4]/*多项式系数*/)
// GS( array[4][4] g[i] e[i] b[i]);
{
double c[4]={0};
double x0[4]={0};
int i,k,j;
double r,sum=0;
for(k=1;;k++)
{
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
sum=a[i][j]*x0[j]+sum;
}
x[i]=x0[i]+(b[i]-sum)/a[i][i];
// n-1
//x =(d -∑ a x )/a
// i i j=0 ij j ii
c[i]=fabs(x[i]-x0[i]);//精度
x0[i]=x[i];
sum=0;
}
r=maxB(c);//转到下一段double max
if(r<0.00000001)//给定精度要求满足则结束迭代
{
// cout<<"解得的三次拟合曲线系数为:\n";
// for(i=0;i<4;i++)
// cout<<"A"<<i<<"="<<x[i]<<endl;
break;
}
}
return 0;
}
double maxB(double array[4])
{
double a=array[0];
int i;
for(i=0;i<4;i++)
if(a<array[i])
a=array[i];
return a;//取最大值
}
//////////////////////////////////////////////////
以下是可以单独运行的CPP版本
#include<iostream>
#include<fstream>
#include<math.h>
#include <iomanip>
using namespace std;
double max(double array[4]);
double gt(double x[11],double y[11]);
double GS(double a[4][4],double b[4],double e[],double s[]);
void main()
{
double a[11]={1,1,1,1,1,1,1,1,1,1,1},b[11],c[11],d[11],e[11],f[10],g[4];
int i;
char strl[10];//存放文件名
cout<<"\n输入文件名:";//输入位于当前文件夹内的shuru.txt即可。
cin>>strl;
ifstream fin(strl);
if (!fin)
{cout<<"cant open"<<strl<<endl;exit(1);}
for(i=0;i<11;i++)//读入n个数据点
{fin>>b[i];fin>>e[i];//左列写入x,右列写入y
c[i]=b[i]*b[i];//x平方
d[i]=b[i]*b[i]*b[i];}//x立方
fin.close();//结束输入
f[0]=gt(a,a);f[1]=gt(a,b);f[2]=gt(a,c);f[3]=gt(a,d);f[4]=gt(b,b);f[5]=gt(b,c);f[6]=gt(b,d);
f[7]=gt(c,c);f[8]=gt(c,d);f[9]=gt(d,d);g[0]=gt(a,e);g[1]=gt(b,e);g[2]=gt(c,e);g[3]=gt(d,e);
double array[4][4]={{f[0],f[1],f[2],f[3]},{f[1],f[4],f[5],f[6]},{f[2],f[5],f[7],f[8]},{f[3],f[6],f[8],f[9]}};//生成4*4矩阵
GS(array,g,e,b);
double gt(double x[11],double y[11])
{
double sum=0;
for(int i=0;i<11;i++)
sum=x[i]*y[i]+sum;
return sum;
}//定义gt,二者乘积的累加之和。
double GS(double a[4][4],double b[4],double e[11],double s[11])
// GS( array[4][4] g[i] e[i] b[i]);
{
double c[4]={0};
double x0[4]={0};
int i,k,j;
double x[4];//多项式系数
double r,sum=0;
for(k=1;;k++)
{
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
sum=a[i][j]*x0[j]+sum;
}
x[i]=x0[i]+(b[i]-sum)/a[i][i];
// n-1
//x =(d -∑ a x )/a
// i i j=0 ij j ii
c[i]=fabs(x[i]-x0[i]);//精度
x0[i]=x[i];
sum=0;
}
r=max(c);//转到下一段double max
if(r<0.00000001)//给定精度要求满足则结束迭代
{
cout<<"解得的三次拟合曲线系数为:\n";
for(i=0;i<4;i++)
cout<<"A"<<i<<"="<<x[i]<<endl;
//多项式格式为:A0+A1x+A2x^2+A3x^3=0
break;
}
}
return 0;
}
double max(double array[4])
{
double a=array[0];
int i;
for(i=0;i<4;i++)
{if(a<array[i])
a=array[i];}
return a;}//取最大值