📄 cmath.cpp
字号:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "CMath.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "UnitFeature.h"
#include "Unitarray.h"
#include "Unitarray_second.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define N 27
#define PI 3.1415926
#define epss 0.00001
CMath::CMath()
{
}
CMath::~CMath()
{
}
float __fastcall CMath::maximum(float *x, int n)//时域最大值
{
float t=-20000.0;
for( int i=0;i<n;i++)
{
if(t<x[i])
{
t=x[i];
}
}
return (t);
}
float __fastcall CMath::minimum(float *x, int n)//时域最小值
{
float t=20000.0;
for(int i=0;i<n;i++)
{
if(t>x[i])
{
t=x[i];
}
}
return (t);
}
float __fastcall CMath::aversquare(float *x, int n) //均方根值=有效值
{
float t=0.0;
for(int i=0;i<n;i++)
{
t=t+x[i]*x[i];
}
t=t/n;
t=sqrt(t);
return(t);
}
float __fastcall CMath::kurtosis(float *x, int n)//求峭度值
{
float kur=0.0,k4=0.0,k2=0.0;
for(int i=0;i<n;i++)
{
k4=k4+x[i]*x[i]*x[i]*x[i];
k2=k2+x[i]*x[i];
}
kur=n*k4/(k2*k2);
return(kur);
}
float __fastcall CMath::kurtosis_coeff(float *x, int n)//求峭度因子
{
float rms=0.0,max=0.0,t=0.0;
rms=kurtosis(x,n);
max=aversquare(x,n);
t=rms/max;
return(t);
}
float __fastcall CMath::aver(float *x, int n) //计算平均值
{
float t=0.0;
for(int i=0;i<n;i++){
t+=x[i];
}
t=t/n;
return(t);
}
float __fastcall CMath::average(float *x, int n)//计算绝对均值
{
float t=0.0;
for(int i=0;i<n;i++){
t+=fabs(x[i]);
}
t=t/n;
return(t);
}
float __fastcall CMath::equation(float *x, int n)//计算方差
{
float equa=0.0,u=0.0;
u=aver(x,n);
for(int i=0;i<n;i++) {
equa+=(x[i]-u)*(x[i]-u);
}
equa=equa/n;
return(equa);
}
float __fastcall CMath::p_p(float *x, int n)//计算峰峰值
{
float max=0.0,min=0.0,pp=0.0;
max=maximum(x,n);
min=minimum(x,n);
pp=max-min;
return(pp);
}
float __fastcall CMath::square_equation(float *x, int n)//计算方根幅值
{
float t=0.0;
for(int i=0;i<n;i++)
{
t+=sqrt(fabs(x[i]));
}
t=t/n;
t=t*t;
return(t);
}
float __fastcall CMath::peak_coeff(float *x, int n)//计算峰值系数:峰值与均方根的比值
{
float rms=0.0,max=0.0,t=0.0;
rms=aversquare(x,n);
max=maximum(x,n);
t=max/rms;
return(t);
}
float __fastcall CMath::wave_coeff(float *x, int n)//计算波形系数:均方根与平均幅值的比值
{
float rms=0.0,av=0.0,t=0.0;
rms=aversquare(x,n);
av=average(x,n);
t=rms/av;
return(t);
}
float __fastcall CMath::pulse_coeff(float *x, int n)//计算脉冲值标:峰值与平均幅值的比值
{
float max=0.0,av=0.0,t=0.0;
max=maximum(x,n);
av=average(x,n);
t=max/av;
return(t);
}
float __fastcall CMath::square_equation_coeff(float *x, int n)//裕度因子:峰值与方根幅值的比值
{
float max=0.0,se=0.0,t=0.0;
max=maximum(x,n);
se=square_equation(x,n);
t=max/se;
return(t);
}
int __fastcall CMath::Arraycollection(float * data,int vec)
{
//TODO: Add your source code here
Point_f data_set[N];
int i,j,m;
int Nc;//类型数目初始值
int k;//预期的聚类中心数目
int Z[27];// 初始第i聚类中心的序号
int ThetaN; //每一聚类中最少的样本数目
float ThetaS; //同一聚类域中样本标准差的最大值
float ThetaC; //不同聚类域距离最小值
int L;//每次迭代允许合并的最大聚类对数目
int I;//允许的最多迭代次数
//特征数据组
for(int i=0;i<N;i++)
{
data_set[i].sequence=i;
for(int j=0;j<vec;j++)
{
data_set[i].x[j]=data[i*vec+j];
}
}
//输入起始聚类个数Nc
Nc=3;
//输入初始第i聚类中心的序号
for(i=0;i<Nc;i++)
{
Z[i]=i*5;
}
int Nj[N]; //记录第j个类中元素的个数
Point_z ZArray[N]; //聚类中心
Point_f SAArray[N][N]; //归类后的样本
float DjAv[N];
float Deltaj[N][N];
float Deltajmax[N];
int DeltajmaxCor[N];
float DAv;
int Nreal=N;
int count=0;
float Dij[270];
int Diji[N];
int Dijj[N];
//int q=0;
//int p=0;
float ft;
int it;
int jt;
int flag;
int ss=0;
Point_z Ztp;
Point_z ZArraytp[N];
int Nctp;
char ch;
//int cur=0;
for(i=0;i<N;i++)
{
Nj[i]=0;
}
for(i=0;i<Nc;i++)
{
int ihere=Z[i];
for(j=0;j<vec;j++)
{ //初始聚类中心 Nc*10
ZArray[i].x[j] =data_set[ihere].x[j];
}
}
Step1:
//输入预期聚类中心数目
k=6;
//入每个聚类域中最少的样本数ThetaN
ThetaN=3;
if(N<ThetaN)return 0;
//输入同一聚类域中样本标准差的最大值
ThetaS=10.0;
//输入不同聚类域距离最小值
ThetaC=2.0;
//输入一次可以合并的聚类中心的最多对数
L=1;
//输入最大迭代次数
I=18;
Step2: //将模式样本归类
for(i=0;i<Nc;i++)
{
Nj[i]=0;
}
for(i=0;i<N;i++)
{
//if(data_set[i].sequence==-1)continue; //若该点的序号为-1则说明它是被剔除的
float dis=1.0e+10;
int xx=0;
float ftemp;
for(j=0;j<Nc;j++)
{
ftemp=CalDistance_fz(data_set[i],ZArray[j],vec);
if(ftemp<dis||fabs(dis-ftemp)<epss)
{
xx=j;
dis=ftemp;
}
}
for(m=0;m<vec;m++)
{
SAArray[xx][Nj[xx]].x[m]=data_set[i].x[m];
}
SAArray[xx][Nj[xx]].sequence=data_set[i].sequence;
Nj[xx]=Nj[xx]+1;
}
Step3:
for(j=0;j<Nc;j++) //是否可以去掉一些数据
{
if(Nj[j]<ThetaN)
{
/* for(i=0;i<Nj[j];i++)
{
data_set[SAArray[j][i].sequence].sequence=-1;
}*/
i=j;
int tr=j;
Nreal-=Nj[j];
while(j<Nc-1)
{
for(m=0;m<Nj[j+1];m++)
{
for(int r=0;r<vec;r++)
{
SAArray[j][m].x[r]=SAArray[j+1][m].x[r];
}
SAArray[j][m].sequence=SAArray[j+1][m].sequence;
}
j++;
}
while(i<Nc-1)
{
Nj[i]=Nj[i+1];
i++;
}
Nc--;
j=tr;
goto Step2;
}
}
Step4: //修正各聚类中心
for(j=0;j<Nc;j++)
{
float temx[10];
for(i=0;i<Nj[j];i++)
{
for(m=0;m<vec;m++)
{
temx[m]+=SAArray[j][i].x[m];
}
}
for(m=0;m<vec;m++)
{
ZArray[j].x[m]=temx[m]/Nj[j];
temx[m]=0.0;
}
}
Step5: //计算各聚类域中诸样本与聚类中心的平均距离
float temp=0.0;
for(j=0;j<Nc;j++)
{
for(i=0;i<Nj[j];i++)
{
temp+=CalDistance_fz(SAArray[j][i],ZArray[j],vec);
}
DjAv[j]=temp/Nj[j];
temp=0.0;
}
Step6://计算全部模式样本对应聚类中心的总平均距离
DAv=0;
for(j=0;j<Nc;j++)
{
DAv+=Nj[j]*DjAv[j];
}
DAv/=Nreal;
//第count次聚类结果
num[count]=count+1;//这是第num次归类
//第count次聚类时一共有Nc类
num_Nc[count]=Nc;
for(i=0;i<Nc;i++)
{
//第count次聚类时第 i类的个数
num_Nc_num[count][i]=Nj[i];
//第i个聚类中心是:(%.2f,%.2f)
for(m=0;m<vec;m++)
{
if(vec==10)
{
Form_array->Center[count][i].x[m]=ZArray[i].x[m];
}
if(vec==10)
{
Form_array_second->Center[count][i].x[m]=ZArray[i].x[m];
}
}
//第count次聚类时第 i类包含的元素有
for(j=0;j<Nj[i];j++)
{
enumerate[count][i][j]=SAArray[i][j].sequence+1;
}
}
count++;
Step7:
if(count>=I) goto Step14;
if(Nc<=k/2)goto Step8;
if((count%2==0)||Nc>=2*k) goto Step11;
Step8://计算各聚类中样本距离标准差
for(j=0;j<Nc;j++)
{
float temx[10];
for(i=0;i<Nj[j];i++)
{
for(m=0;m<vec;m++)
{
temx[m]+=(SAArray[j][i].x[m]-ZArray[j].x[m])*(SAArray[j][i].x[m]-ZArray[j].x[m]);
}
}
for(m=0;m<vec;m++)
{
Deltaj[j][m]=sqrt(temx[m]/Nj[j]);
temx[m]=0.0;
}
}
Step9://求每个标准差向量中的最大分量
for(j=0;j<Nc;j++)
{
float rbs=-2000.0;
for(m=0;m<vec;m++)
{
if(Deltaj[j][m]>rbs)
{
rbs=Deltaj[j][m];
DeltajmaxCor[j]=m;
}
}
Deltajmax[j]=rbs;
}
Step10://分裂判断和计算
for(j=0;j<Nc;j++)
{
if(Deltajmax[j]>ThetaS)
{
if((DjAv[j]>DAv&&Nj[j]>2*(ThetaN+1))||Nc<=k/2)
{
float Garma=0.5;
Point_z Zj1,Zj2;
for(m=0;m<vec;m++)
{
Zj1.x[m]=ZArray[j].x[m];
Zj2.x[m]=ZArray[j].x[m];
if(DeltajmaxCor[j]==m)
{
Zj1.x[m]=Zj1.x[m]+Deltajmax[j]*Garma;
Zj2.x[m]=Zj2.x[m]-Deltajmax[j]*Garma;
}
ZArray[j].x[m]=Zj1.x[m];
ZArray[Nc].x[m]=Zj2.x[m];
}
Nc++;
goto Step2;
}
}
}
Step11://计算全部聚类中心的距离
ss=0;
for(i=0;i<Nc-1;i++)
{
for(j=i+1;j<Nc;j++)
{
Dij[ss]=CalDistance_z(ZArray[i],ZArray[j],vec);
Diji[ss]=i;
Dijj[ss]=j;
ss++;
}
}
Step12: //简单起见,只考虑一次只合并一对聚类中心的情况
//找出类间距离最小的
ft=Dij[0];
it=Diji[0];
jt=Dijj[0];
for(i=1;i<ss;i++)
{
if(Dij[i]<ft)
{
ft=Dij[i];
it=Diji[i];
jt=Dijj[i];
}
}
Step13:
if(ft<ThetaC)
{
for(m=0;m<vec;m++)
{
Ztp.x[m]=(Nj[it]*ZArray[it].x[m]+Nj[jt]*ZArray[jt].x[m])/(Nj[it]+Nj[jt]);
ZArray[it].x[m]=Ztp.x[m];
}
j=jt;
while(j<Nc-1)
{
for(m=0;m<vec;m++)ZArray[j].x[m]=ZArray[j+1].x[m];
j++;
}
j=jt;
while(j<Nc-1)
{
Nj[j]=Nj[j+1];
j++;
}
Nc--;
}
Step14:
if(count>=I)
{
count=0;
return 0;
}
else
{
goto Step2;
}
}
float __fastcall CMath::Distance(float * data_a, float* data_b, int n)
{
//TODO: Add your source code here
float dis=0.0;
for(int i=0;i<n;i++)
{
dis+=(data_a[i]-data_b[i])*(data_a[i]-data_b[i]);
}
dis=sqrt(dis);
return dis;
}
float __fastcall CMath::CalDistance_f(Point_f x1, Point_f x2,int vec)
{
//TODO: Add your source code here
float re=0;
for(int i=0;i<vec;i++)
{
re+=(x1.x[i]-x2.x[i])*(x1.x[i]-x2.x[i]);
}
re=sqrt(re);
return re;
}
float __fastcall CMath::CalDistance_z(Point_z x1, Point_z x2,int vec)
{
//TODO: Add your source code here
float re=0;
for(int i=0;i<vec;i++)
{
re+=(x1.x[i]-x2.x[i])*(x1.x[i]-x2.x[i]);
}
re=sqrt(re);
return re;
}
float __fastcall CMath::CalDistance_fz(Point_f x1, Point_z x2,int vec)
{
//TODO: Add your source code here
float re=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -