📄 dlg_location.cpp
字号:
// Dlg_location.cpp : implementation file
//
#include "stdafx.h"
#include "dataanalisis.h"
#include "Dlg_location.h"
#include "Dlg_common.h"
#include "MainFrm.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlg_location dialog
CDlg_location::CDlg_location(CWnd* pParent /*=NULL*/)
: CDialog(CDlg_location::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlg_location)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CDlg_location::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlg_location)
DDX_Control(pDX, IDC_EDIT2, m_y);
DDX_Control(pDX, IDC_EDIT1, m_x);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlg_location, CDialog)
//{{AFX_MSG_MAP(CDlg_location)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlg_location message handlers////
const int N=100;//用户输入的数据对个数最大不能超过N
double x3[N],y3[N];//存储用户输入的自变量和因变量
double x[N],y[N];//存储预处理后的自变量和因变量的值
double px[N],py[N],yp[N];//存储排序后自变量、因变量的频率和与之对应的因变量
double ppx[N],ppy[N];//存储频率值
double DX=0,DY=0;//方差
double averagex,averagey;//平均数
double middata;//中位数
double minlicha,licha1,licha2,licha3,licha4;//定义离差变量
double k,b1;//线性模型y=k*x+b1的系数
double a,b,c;//二次曲线模型y=a*x^2+b*x+c的系数
double k1,a1;//指数模型y=k1*pow(a1,x)的系数
double k3,a3;//对数模型y=k3*log(a3,x)的系数
double yuchuli(double x0[],double y0[],int n);
double zhishu(double x[],double y[],int n);
double linexing(double x[],double y[],int n);
double erciquxian(double x[],double y[],int n);
double duishu(double x[],double y[],int n);
double licha();
double pinshu(double x3[],double y3[],int n);
double fangcha(double x3[],double y3[],int n);
double averagezhi(double x3[],double y3[],int n);
double zhongweishu(double x3[],double y3[],int n);
double input(int n);
void CDlg_location::OnOK()
{
// TODO: Add extra validation here
extern int n;
extern int g;
char cEdit1[10],cEdit2[10];
m_x.GetWindowText(cEdit1,10);
m_y.GetWindowText(cEdit2,10);
x3[g]=atof((LPCTSTR)cEdit1);
y3[g]=atof((LPCTSTR)cEdit2);
x[g]=x3[g];
y[g]=y3[g];
g++;
if(g<n)
{
CDialog::OnOK();
CDlg_location location;
location.DoModal();
}
else
{
yuchuli(x3,y3,n);//调用数据预处理模块对数据进行处理
linexing(x,y,n);//调用线性模型
erciquxian(x,y,n);//调用二次曲线模型
zhishu(x,y,n);//调用指数模型
duishu(x,y,n);//调用对数模型
licha();
pinshu(x3,y3,n);
fangcha(x3,y3,n);
//averagezhi(x3,y3,n);
zhongweishu(x3,y3,n);
}
CDialog::OnOK();
// CDlg_common common;
// common.DoModal();
}
//////////////////////////////////////////////////////////////////////
///数据预处理模块////
int mid;//修改时用来存储中间变量的值
double kuaixiugai(int low,int high);
double yuchuli(double x[],double y[],int n)
{
int j;
double sum=0;//一个累加器
double a[N],b;//数组a[N]用来存储相邻数据的变化速率即斜率,b为其平均数
for(int i=0;i<n;i++) //计算出相邻数据的斜率
a[i]=(y[i+1]-y[i])/(x[i+1]-x[i]);
for(i=0;i<n-1;i++) //计算总量
sum+=fabs(a[i]);
b=sum/(n-1);//计算平均数
/*处理单个和块异常数据*/
for(i=0;i<n;i++)
{
if(fabs(a[i])>b&&fabs(a[i-1])>b)//单个异常数据的检测
{
x[i]=(x[i-1]+x[i+1])/2;
y[i]=(y[i-1]+y[i+1])/2;
}
if(fabs(a[i])>b&&fabs(a[i+1])<b)//块异常数据的检测
{
for(j=i;j<n;j++)//查找块异常数据的末位置
j++;
j++;//对应在数组x[]和y[]中的位置
kuaixiugai(i,j);//调用块修改递归算法
}
}
return x[N];
return y[N];
}
double kuaixiugai(int low,int high)
{//利用递归算法实现的块修改功能模块
int k0=-1;
if(k0==-1) k0=high;
mid=(low+high)/2;
if(low!=mid&&high<k0)
{
x[mid]=(x[low]+x[high])/2;
y[mid]=(y[low]+y[high])/2;
high=mid;
kuaixiugai(low,high);
}
if(high<k0)
{
low=high*2-low;
high=(high+1)*2-high;
kuaixiugai(low,high);
}
return x[N];
return y[N];
}
///////////////////////////////////////////////////////////////////////
////线性模型模块////
double linexing(double x[],double y[],int n)
{
/*…………………k和b分别是线形方程y=k*x+b的系数和截距,
sum,sum1,sum2,sum3,sum4分别存储累加的和……………*/
double sum=0,sum1=0,sum2=0,sum3=0,sum4=0;
for(int i=0;i<n;i++)
{
sum1+=x[i];
sum2+=x[i]*x[i];
sum3+=y[i];
sum4+=x[i]*y[i];
}
k=(double(sum3*sum1-sum4*n))/(sum1*sum1-sum2*n);//计算系数k
b1=(double(sum4*sum1-sum3*sum2))/(sum1*sum1-sum2*n);//计算截距b
/////计算离差////
for(i=0;i<n;i++)
sum+=fabs(y[i]-(k*x[i]+b1));
licha1=sum/n;
return k;
return b1;
}
////////////////////////////////////////////////////////////////////////
////二次曲线模型模块////
double erciquxian(double x[],double y[],int n)
{
double D;//一个变量作为分母
double sum=0,sum1=0,sum2=0,sum3=0,sum4=0,sum5=0,sum6=0,sum7=0;//定义一些累加器
for(int i=0;i<n;i++)
{
sum1+=x[i];
sum2+=x[i]*x[i];
sum3+=x[i]*x[i]*x[i];
sum4+=x[i]*x[i]*x[i]*x[i];
sum5+=y[i];
sum6+=y[i]*x[i];
sum7+=y[i]*x[i]*x[i];
}
D=((sum4*sum2-sum3*sum3)*(sum2*sum1-sum3*n)-(sum4*sum1-sum2*sum3)*(sum2*sum2-sum1*sum3));
a=((sum7*sum2-sum6*sum3)*(sum2*sum1-sum3*n)-(sum7*sum1-sum5*sum3)*(sum2*sum2-sum1*sum3))/D;//计算系数a
c=((sum7*sum2-sum6*sum3)*(sum4*sum1-sum2*sum3)-(sum7*sum1-sum5*sum3)*(sum4*sum2-sum3*sum3))/D;//计算系数c
b=(sum7-a*sum4-c*sum2)/sum3;//计算系数b
/////计算离差/////
for(i=0;i<n;i++)
sum+=fabs(y[i]-(a*x[i]*x[i]+b*x[i]+c));
licha2=sum/n;
return a;
return b;
return c;
}
///////////////////////////////////////////////////////////////////////
////指数模型模块////
double zhishu(double x[],double y[],int n)
{
double Y[N];
double k2,a2,sum=0,sum1=0,sum2=0,sum3=0,sum4=0;
double c[N];
for(int i=0;i<n;i++)
{
c[i]=x[i];
x[i]=y[i];
y[i]=c[i];
}
for(i=0;i<n;i++)
{
if(y[i]>0)
Y[i]=log(y[i]);
}
for(i=0;i<n;i++)
{
if(Y[i]>0)//判断y值是否大于0,否则就不适合指数模型
{
for(i=0;i<n;i++)
{
sum1+=x[i];
sum2+=x[i]*x[i];
sum3+=y[i];
sum4+=x[i]*y[i];
}
a2=(double(sum3*sum1-sum4*n))/(sum1*sum1-sum2*n);
k2=(double(sum4*sum1-sum3*sum2))/(sum1*sum1-sum2*n);
a1=exp(a2);
k1=exp(k2);
}
else
return 0;
}
////计算离差////
for(i=0;i<n;i++)
sum+=fabs(y[i]-(k1*pow(a1,x[i])));
licha3=sum/n;
return k1;
return a1;
}
///////////////////////////////////////////////////////////////////////
////对数模型模块////
double duishu(double X[],double Y[],int n)
{
double c[N],sum=0;
for(int i=0;i<n;i++)
{//交换x和y的位置,来调用指数模型的功能模块
c[i]=X[i];
X[i]=Y[i];
Y[i]=c[i];
}
zhishu(X,Y,n);//调用指数模型模块
k3=k1;
a3=a1;
////计算离差////
for(i=0;i<n;i++)
sum+=fabs(y[i]-(k3*pow(a3,x[i])));
licha4=sum/n;
return k3;
return a3;
}
////////////////////////////////////////////////////////////////////////
////比较离差////
double licha()
{
minlicha=licha1;
if(minlicha>licha2)
minlicha=licha2;
if(minlicha>licha3)
minlicha=licha3;
if(minlicha>licha4)
minlicha=licha4;
return minlicha;
}
////////////////////////////////////////////////////////////////////////
////统计频率功能模块程序////
double pinshu(double x3[],double y3[],int n)
{
for(int i=0;i<n;i++)
{
ppx[i]=1;
ppy[i]=1;
}
for(i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(j==i);
else
{
if(x3[i]==x3[j])//统计x[]中每个数据出现的次数
ppx[i]++;
if(y3[i]==y3[j])//统计y[]中每个数据出现的次数
ppy[i]++;
}
}
for(i=0;i<n;i++)
{
ppx[i]=double(ppx[i])/n;//计算x中每个数据出现的频率
ppy[i]=double(ppy[i])/n;//计算y中每个数据出现的频率
}
for(i=0;i<n;i++)//排序因变量数据出现的频率,取频率前5个大值
{
for(int j=1;j<n;j++)
if(ppy[i]<ppy[j])
{
py[i]=ppy[j];
yp[i]=y3[j];
}
}
return ppy[N];
return yp[N];
return py[N];
}
/////////////////////////////////////////////////////////////////
/////计算方差/////
double fangcha(double x3[],double y3[],int n)
{
double EX=0,EY=0;
//pinshu(x3,y3,n);//调用统计频数功能函数
averagezhi(x3,y3,n);
for(int i=0;i<n;i++)
{
EX+=ppx[i]*x3[i];//计算x的数学期望
EY+=ppy[i]*y3[i];//计算y的数学期望
}
for(int j=0;j<n;j++)
{
DX+=(EX-averagex)* (EX-averagex);//计算x的方差
DY+=(EY-averagey)* (EY-averagey); //计算x的方差
}
return DX;
return DY;
}
//////////////////////////////////////////////////////////////////
////计算均值程序模块////
double averagezhi(double x3[],double y3[],int n)
{
double sumx=0,sumy=0;
for(int i=0;i<n;i++)
{
sumx+=x3[i];//计算x[]的总数
sumy+=y3[i];//计算y[]的总数
}
averagex=sumx/n; //计算x[]的平均数
averagey=sumy/n; //计算x[]的平均数
return averagex;
return averagey;
}
///////////////////////////////////////////////////////////////////
//////计算中位数////////////
double zhongweishu(double x3[],double y3[],int n)
{
double temp,y4[N];
for(int i=0;i<n;i++)
y4[i]=y3[i];
for(i=0;i<n;i++)//对y的数据进行排序,以便找出它们的中位数
for(int j=0;j<n-i-1;j++)
{
if(y4[j]>y4[j+1])//冒泡排序,从小到大
{
temp=y4[j];
y4[j]=y4[j+1];
y4[j+1]=temp;
}
}
if(n%2==1)
middata=y4[n/2];
else
middata=y4[n/2-1];
return middata;
}
///////////////////////////////////////////////////////////////////
void CDlg_location::OnCancel()
{
// TODO: Add extra cleanup here
CDialog::OnCancel();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -