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

📄 lvq_engi.c

📁 VQ压缩算法
💻 C
字号:
/*==================================================*/
/* This is the engine of Khonen's LVQ3 algorithm    */
/*--------------------------------------------------*/
/*                                                  */
/* Author : Jialong He                              */
/* Date   : March 14, 1995                          */
/* Modify : April 25, 1998, add linked list         */
/*==================================================*/
#include <stdlib.h>
#include <stdio.h>
#include "vq_model.h"

extern   int verbose;

/*------------------------------------------------*/
/* train the codebook by Kohonen's LVQ3 algorithm */
/*------------------------------------------------*/
void LVQ_engine (DType *DataHead, DType *CodeHead, int TotalClass,
		 float alpha, float epsilon, float WinSize, int epoch) {

     int TotalVector = 0, Loops;  /* total training step */
     int VecUpdate_1 = 0, VecUpdate_2 = 0, VecUpdate_3 = 0;

     int ClassCnt, CodeCnt, DimCnt, EpochCnt = 1;
     int Total_Loops, VecDim;
     int DataClass, VectorID;
     int   FClass, SClass, FSeq, SSeq;

     float ratio, FirstDis, SecondDis, CurrDis;
     float talpha, CurrWin = WinSize;

     for (ClassCnt=0; ClassCnt<TotalClass; ClassCnt++)
	TotalVector += DataHead[ClassCnt].VecNum;

     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 %d\n",
		  EpochCnt++, VecUpdate_1, VecUpdate_2, VecUpdate_3);
	  VecUpdate_1 = 0;
	  VecUpdate_2 = 0;
	  VecUpdate_3 = 0;
       }

       /*-----------------------------------------*/
       /* randomly select a training vector       */
       /*-----------------------------------------*/
       DataClass  = my_random() % TotalClass;
       VectorID   = my_random() % DataHead[DataClass].VecNum;

       talpha = alpha * Loops / Total_Loops;
       CurrWin = WinSize *  Loops / Total_Loops + 0.05;

       FirstDis = LARGE; FClass = 0; FSeq = 0;
       SecondDis = LARGE;
       /*-----------------------------------------------------*/
       /* find the nearest and second nearest code vectors    */
       /*-----------------------------------------------------*/
       for (ClassCnt=0; ClassCnt<TotalClass; ClassCnt++) {
	  for (CodeCnt=0; CodeCnt<CodeHead[ClassCnt].VecNum; CodeCnt++) {
	    DIST_VEC(CodeHead[ClassCnt].Mat[CodeCnt], DataHead[DataClass].Mat[VectorID],
		 CurrDis, VecDim, float, float);

	   if (CurrDis < FirstDis) {
	     SecondDis = FirstDis;
	     SClass    = FClass;
	     SSeq      = FSeq;
	     FirstDis  = CurrDis;
	     FClass    = ClassCnt;
	     FSeq      = CodeCnt;
	   }
	   else if (CurrDis < SecondDis) {
	     SecondDis  = CurrDis;
	     SClass     = ClassCnt;
	     SSeq       = CodeCnt;
	   }

	  }   /* CodeCnt */
       }      /* ClassCnt */

       if (SecondDis!=0)  ratio = FirstDis / SecondDis;

       /*-------------------------------------------------------*/
       /* if the training vector falls into the window          */
       /*-------------------------------------------------------*/
       if (ratio > ((1.0 - CurrWin)/(1.0 + CurrWin))) {

	  /*-------------------------------------------*/
	  /* The nearest code has same class as data   */
	  /*------------------------------------------*/
/*1*/     if ((CodeHead[FClass].ID == DataHead[DataClass].ID) &&
	      (CodeHead[SClass].ID != DataHead[DataClass].ID)) {

	    for (DimCnt = 0; DimCnt < VecDim; DimCnt++) {
	      CodeHead[FClass].Mat[FSeq][DimCnt] += talpha * (DataHead[DataClass].Mat[VectorID][DimCnt] -
				    CodeHead[FClass].Mat[FSeq][DimCnt]);

	      CodeHead[SClass].Mat[SSeq][DimCnt] -= talpha * (DataHead[DataClass].Mat[VectorID][DimCnt] -
				    CodeHead[SClass].Mat[SSeq][DimCnt]);
	    }

	  VecUpdate_1++;
	  }

	  /*-------------------------------------------*/
	  /* The second nearest code has same class    */
	  /*-------------------------------------------*/
/*2*/	  if ((CodeHead[FClass].ID != DataHead[DataClass].ID) &&
	      (CodeHead[SClass].ID == DataHead[DataClass].ID)) {

	    for (DimCnt = 0; DimCnt < VecDim; DimCnt++) {
	      CodeHead[FClass].Mat[FSeq][DimCnt] -= talpha * (DataHead[DataClass].Mat[VectorID][DimCnt] -
				    CodeHead[FClass].Mat[FSeq][DimCnt]);

	      CodeHead[SClass].Mat[SSeq][DimCnt] += talpha * (DataHead[DataClass].Mat[VectorID][DimCnt] -
				    CodeHead[SClass].Mat[SSeq][DimCnt]);
	    }
	    VecUpdate_2++;
	  }
       }    /* if ratio */

      /*-------------------------------------------*/
      /* Both codes have same class as training vec*/
      /*-------------------------------------------*/
/*3*/ if ((CodeHead[FClass].ID == DataHead[DataClass].ID) &&
	      (CodeHead[SClass].ID == DataHead[DataClass].ID)) {

	    for (DimCnt = 0; DimCnt < VecDim; DimCnt++) {
	      CodeHead[FClass].Mat[FSeq][DimCnt] += talpha * (DataHead[DataClass].Mat[VectorID][DimCnt] -
				    CodeHead[FClass].Mat[FSeq][DimCnt]) * epsilon;

	      CodeHead[SClass].Mat[SSeq][DimCnt] += talpha * (DataHead[DataClass].Mat[VectorID][DimCnt] -
				    CodeHead[SClass].Mat[SSeq][DimCnt]) * epsilon;
	    }
      VecUpdate_3++;
      }

     }   /* while (Loops--) */

}

⌨️ 快捷键说明

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