📄 lvq_engi.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 + -