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

📄 gvq_engi.c

📁 VQ压缩算法
💻 C
字号:
/*==================================================*/
/* This is the GVQ algorithm proposed by Jialong HE */
/* It minimizes the error rate for vector goupes.   */
/*--------------------------------------------------*/
/*                                                  */
/* Author : Jialong He                              */
/* Date   : March 3, 1996                           */
/* Modify : April 25, 1998                          */
/*                                                  */
/* Note: window size is important   (win = 1)       */
/* First != DataID is better than Second == DataID  */
/*==================================================*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "vq_model.h"
#define  MaxOptN 100

extern   int verbose;

/*--------------------------------------------*/
/* train the codebook with the GVQ algorithm  */
/*--------------------------------------------*/
void GVQ_engine (DType *DataHead, DType *CodeHead, int TotalClass,
		 float alpha, float WinSize, int epoch, int OptN, int SeqSel) {

     int Loops, DataClass, CodeClass;
     int CodeCnt, DimCnt, EpochCnt = 1;
     int VecUpdate_1 = 0, VecUpdate_2 = 0;
     float *AccuDis, shortest, nshortest;
     float talpha, Ratio, Total_Loops, CurrWin, TmpFloat;
     int First, IndCnt;
     int ClsCnt, **NCode;     /* index of nearest codes, */
     int IndArr[MaxOptN];               /* Indices of a group optimized vectors */
     int DataID, VecDim;

     int TotalCode = 0, TotalVector = 0;

     /*---------------------------------------*/
     /* Total Code and Training vector number */
     /*---------------------------------------*/
     for (ClsCnt=0; ClsCnt< TotalClass; ClsCnt++) {
       TotalCode   += CodeHead[ClsCnt].VecNum;
       TotalVector += DataHead[ClsCnt].VecNum;
     }

     MArray_1D(AccuDis, TotalClass, float, "AccuDis");
     MArray_2D(NCode,   TotalClass, OptN, int, "NCode");

     VecDim = DataHead[0].VecDim;
     Loops = epoch * TotalVector;
     Total_Loops = Loops;
     while (Loops--) {

       /*--------------------------------------*/
       /* One Epoch finished                   */
       /*--------------------------------------*/
       if ((Loops % TotalVector) == 0) {
	fprintf(stderr, "Epoch %d, Vector Updated %d %d\n", EpochCnt++, VecUpdate_1, VecUpdate_2);
	VecUpdate_1  = 0;
	VecUpdate_2  = 0;
       }

       /*---------------------------*/
       /* randomly select a speaker */
       /*---------------------------*/
       DataClass = my_random() % TotalClass;

       /*---------------------------------------------------*/
       /* find CodeClass which has the same ID as DataClass */
       /* Usually, CodeClass == DataClass                   */
       /*---------------------------------------------------*/
       for (ClsCnt=0; ClsCnt< TotalClass; ClsCnt++) {
	 if (DataHead[DataClass].ID == CodeHead[ClsCnt].ID) {
	   CodeClass = ClsCnt;
	   break;
         }
       }

       if (SeqSel) {
	 DataID =  my_random() % (DataHead[DataClass].VecNum-OptN);
	 for (IndCnt=0; IndCnt<OptN; IndCnt++)
	   IndArr[IndCnt] = DataID+IndCnt;
       }
       else {             /* randomly select vectors */
	 for (IndCnt=0; IndCnt<OptN; IndCnt++)
	   IndArr[IndCnt] = my_random() % DataHead[DataClass].VecNum;
       }

       /*-------------------------------------------------*/
       /* learning rate and window size linearly decrease */
       /*-------------------------------------------------*/
       talpha  = alpha * Loops / Total_Loops;
       CurrWin = WinSize * Loops / Total_Loops + 0.1;

       /*----------------------------------------------*/
       /* Accumulated Euclidean distance to each code  */
       /*----------------------------------------------*/
       for (ClsCnt=0; ClsCnt< TotalClass; ClsCnt++) {  /* each code class */
	 AccuDis[ClsCnt] = 0.0;
	 for (IndCnt=0; IndCnt<OptN; IndCnt++) {  /* for vectors in a group */
	    shortest = LARGE; First = 0;
	    for (CodeCnt=0; CodeCnt<CodeHead[ClsCnt].VecNum; CodeCnt++) {
	      DIST_VEC(CodeHead[ClsCnt].Mat[CodeCnt], DataHead[DataClass].Mat[IndArr[IndCnt]],
		       TmpFloat, VecDim, float, float);
	      if (TmpFloat < shortest) {
		shortest = TmpFloat;
		First    = CodeCnt;
              }
	    }  /* for (CodeCnt) */

	    AccuDis[ClsCnt] += shortest;
	    NCode[ClsCnt][IndCnt] = First;

	 }  /* for (IndCnt) */
       }  /* for (ClsCnt) */


       /*-----------------------------------------------*/
       /* find out code class with min average distance */
       /*-----------------------------------------------*/
       shortest = LARGE;
       First = 0;
       for (DimCnt=0; DimCnt<TotalClass; DimCnt++) {
	  if (AccuDis[DimCnt] < shortest) {
	     shortest = AccuDis[DimCnt];
	     First = DimCnt;
	  }
       }

       if (AccuDis[CodeClass] != 0)
	  Ratio = (AccuDis[CodeClass] - AccuDis[First]) / AccuDis[CodeClass];

       /*-------------------------------------------------------*/
       /* if nearest class is not the class of vectors, learn   */
       /*-------------------------------------------------------*/
       if ((DataHead[DataClass].ID != CodeHead[First].ID) && (Ratio < CurrWin)) {

	 VecUpdate_1++;
	 for (IndCnt=0; IndCnt<OptN; IndCnt++) {
	   /*----------------------------------------------------*/
	   /* for each data vector, find out distance to nearest */
	   /* code vectors of class First/DataID		 */
	   /*----------------------------------------------------*/
	   DIST_VEC(CodeHead[First].Mat[ NCode[First][IndCnt]], DataHead[DataClass].Mat[IndArr[IndCnt] ],
		       shortest, VecDim, float, float);

	   DIST_VEC(CodeHead[DataClass].Mat[ NCode[DataClass][IndCnt]], DataHead[DataClass].Mat[IndArr[IndCnt] ],
		       nshortest, VecDim, float, float);

	   /*-----------------------------------------*/
	   /* adjust only misclassified vectors       */
	   /* First is wrong code, DataID is correct  */
	   /*-----------------------------------------*/
	   if  (shortest<nshortest) {
	      for (DimCnt = 0; DimCnt < VecDim; DimCnt++) {
		CodeHead[First].Mat[ NCode[First][IndCnt] ][DimCnt] -= talpha * (DataHead[DataClass].Mat[IndArr[IndCnt]][DimCnt] -
			    CodeHead[First].Mat[ NCode[First][IndCnt] ][DimCnt]);

		CodeHead[CodeClass].Mat[ NCode[CodeClass][IndCnt] ][DimCnt] += talpha * (DataHead[DataClass].Mat[IndArr[IndCnt]][DimCnt] -
			    CodeHead[CodeClass].Mat[ NCode[CodeClass][IndCnt] ][DimCnt]);

	      }
	   }  /* if shortest */
	 }    /* for IndCnt */
       }    /* if (First != DataID) */

       /*----------------------------------------------------------*/
       /* keep the codebook approximate density                    */
       /*----------------------------------------------------------*/
       else {
	if (DataHead[DataClass].ID == CodeHead[First].ID)  {
	  for (IndCnt=0; IndCnt<OptN; IndCnt++) {
	   for (DimCnt = 0; DimCnt < VecDim; DimCnt++)
		CodeHead[First].Mat[ NCode[First][IndCnt] ][DimCnt] += 0.1 * talpha * (DataHead[DataClass].Mat[IndArr[IndCnt]][DimCnt] -
			    CodeHead[First].Mat[ NCode[First][IndCnt] ][DimCnt]);
	  }
	  VecUpdate_2++;
	}
       }  /* else */
     }   /* while (Loops--) */

     MFree_1D(AccuDis);
     MFree_2D(NCode);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -