⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmath.cpp

📁 模式识别程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------


#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 + -