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

📄 matlvq.cpp

📁 face recognition test source code
💻 CPP
字号:
/*********************************************************************************************
* MatLvq makes the convertion between the matrix paradigm which is employed in the PCA dll,
* and the LVQ paradigm.
* 
* Written by Sami Romdhani Jully 1996
*********************************************************************************************/

#include "header.h"
#include "lvq.h"
#include "matlvq.h"

#include "tools.h"

#include "clabel.h"
#include "lvq_pak.h"
#include "lvq_rout.h"

#include <stdlib.h>
#include <malloc.h>

CLabel *plabel = NULL;						/*points to the beginning of the label's list*/

/*********************************************************************************************
* MattoEntries copy the values the elements of the CMatrix pmat to the entries pentries
*********************************************************************************************/
int MattoEntries(struct entries **pentries, CMatrix *pmat)
	{
	long l, max, l2, max2;
	struct data_entry *current, *prev;
	char str[MAX_NAME];
	
	*pentries = alloc_entries();
	if (*pentries == NULL)
		return -1;
	
	(*pentries)->dimension = pmat->GetLi();
	(*pentries)->num_loaded = pmat->GetCol();
	(*pentries)->num_entries = pmat->GetCol();
	max = (*pentries)->num_entries;
	max2 = (*pentries)->dimension;
	
	pmat->Lock();
	for (l = 0; l < max; l++)
		{
		current = (struct data_entry *)malloc(sizeof(struct data_entry));
      if (current == NULL)
			{
	  		Msg(0, "not enough memory");
			pmat->Unlock();
	  		return -1;
			}
		if (l > 0)
			prev->next = current; 
      
      current->next = NULL;
      current->fixed = NULL;
      current->mask = NULL;
      current->lab.label_array = NULL;
      current->lab.label = LABEL_EMPTY;
      current->num_labs = 0;
      
      current->points = (float*)calloc((*pentries)->dimension, sizeof(float));
      if (current->points == NULL)
			{
	  		free(current);
	  		Msg(0, "not enough memory");
			pmat->Unlock();
			return -1;
			}
      
      for (l2 = 0; l2 < max2; l2++)
      	current->points[l2] = pmat->GetAt(l2+1, l+1);
      
		pmat->GetColName(l+1, str, sizeof(str));
		plabel->SetLabel(current, str);
		
		current->weight = 0;

		if (l == 0)
			(*pentries)->entry = current;
		prev = current;
		}
	pmat->Unlock();
	(*pentries)->current = (*pentries)->entry;
		
	return 0;
	}

/*********************************************************************************************
* EntriestpMat copy the values the elements of the entries pentries to the CMatrix pmat
*********************************************************************************************/
int EntriestoMat(CMatrix **pmat, struct entries *pentries)
	{
	long row, col, max_row, max_col;
	struct data_entry *current;
	
	if (*pmat == NULL)
		{
		*pmat = new CMatrix(pentries->dimension, pentries->num_entries);
		if (*pmat == NULL)
			return -1;
		}
	
	max_row = (*pmat)->GetLi();
	max_col = (*pmat)->GetCol();
	
	if (max_row != pentries->dimension || max_col != pentries->num_entries)
		{
		Msg(0, "EntriestoMat : not the same dim");
		return -1;
		}
	
	(*pmat)->Lock();
	current = pentries->entry;
   for (col = 0; col < max_col; col++)
		{
		if (current == NULL)
			break;
			
		for (row = 0; row < max_row; row++)
			{
      	(*pmat)->SetAt(row+1, col+1, current->points[row]);
         }
		(*pmat)->SetColName(col+1, plabel->GetLabel(current));
		
		current = current->next;
		}
	(*pmat)->Unlock();
	
	if (col != max_col)
		return -1;
		
	return 0;
	}

/*********************************************************************************************
* LVQInit performs the initialization of some varibles needed for the processing of LVQ.
* It Must be called before the processing.
*********************************************************************************************/
int LVQInit(PLVQPARAMS params)
	{
	plabel = new CLabel();
	params->sammon = NULL;
	
	/*Set the initial values*/
	params->noc = -1;
	params->knn = -1;
	params->xdim = -1;
	params->ydim = -1;
	params->neigh = NEIGH_UNKNOWN;
	params->topol = TOPOL_UNKNOWN;
	params->alpha_type = ALPHA_UNKNOWN;
	params->radius = -1;
	params->alpha = -1;
	params->length = -1;
	params->winlen = -1;
	params->epsilon = -1;
	
	return 0;
	}

/*********************************************************************************************
* LVQEnd frees the memory allocated in the function LVQInit.
* It must be called at the end of the processing of LVQ.
*********************************************************************************************/
int LVQEnd(PLVQPARAMS params)
	{
	if (plabel != NULL)
		delete plabel;
	/*if (params->sammon != NULL)
		delete params->sammon;*/
	return 0;
	}

int NumClass()
	{return plabel->NumClass();}

int GetClassInt(int i)
	{
	return plabel->GetClassInt(i);
	}

int GetLabelInt(char *str)
	{
	return plabel->GetLabelInt(str);
	}

char *GetClassStr(int i)
	{
	return plabel->GetClassStr(i);
	}
				
/*********************************************************************************************
* Delete the memory allowed for pentries.
*********************************************************************************************/
int DeleteEntries(struct entries *pentries)
	{
	close_entries(pentries);
	return 0;
	}

/*********************************************************************************************
* Converts PLVQPARAMS params into struct teach_params *tparams
* This function makes the connection between the paradigm used in PCA and the paradigm used in 
* LVQ
*********************************************************************************************/
int LVQParamstoTeach(struct teach_params *tparams, PLVQPARAMS params)
	{
	MattoEntries(&(tparams->codes), params->pcode);
	if (tparams->codes == NULL)
		return -1;
	tparams->codes->xdim = params->xdim;
	tparams->codes->ydim = params->ydim;
	tparams->codes->topol = params->topol;
	tparams->codes->neigh = params->neigh;
	
	MattoEntries(&(tparams->data), params->pdata);
	if (tparams->data == NULL)
		{
		DeleteEntries(tparams->codes);
		return -1;
		}
	tparams->data->xdim = params->xdim;
	tparams->data->ydim = params->ydim;
	tparams->data->topol = params->topol;
	tparams->data->neigh = params->neigh;
	
	tparams->topol = params->topol;
	tparams->neigh = params->neigh;
	tparams->alpha_type = params->alpha_type;
	tparams->radius = params->radius;
	tparams->alpha = params->alpha;
	tparams->length = params->length;
	tparams->knn = params->knn;
	tparams->snapshot = NULL;
	tparams->start_time = 0;
	tparams->end_time = 0;
	
	tparams->mapdist = NULL;
	tparams->dist = vector_dist_euc;
	tparams->neigh_adapt = NULL;
	tparams->vector_adapt = adapt_vector;
	if (params->knn > 1)
		tparams->winner = find_winner_knn;
	else
		tparams->winner = find_winner_euc;
	switch (tparams->alpha_type)
		{
		case ALPHA_LINEAR:
			tparams->alpha_func = linear_alpha;
			break;
		case ALPHA_INVERSE_T:
			tparams->alpha_func = inverse_t_alpha;
			break;
		case ALPHA_UNKNOWN:
		default:
			tparams->alpha_func = NULL;
		}
	tparams->sammon = params->sammon;
	
	/*Checks*/
	if (tparams->alpha < 0.0 || tparams->alpha > 1.0)
		tparams->alpha = 0.3;
	
	return 0;
	}

/*-------------------------------------- LINK ROUTINES ---------------------------------------*/

/***********************************************************************************************
* lvq1 : original LVQ1 learning algorithm
***********************************************************************************************/
int lvq1(PLVQPARAMS params)
	{
	int ret;
	struct teach_params tparams;
	struct entries *pcode;
	
	if (params->radius == -1)
		{
		params->radius = 90.0;
		Msg(0, "Radius is undefined, default value = %f", params->radius);
		}
	if (params->alpha == -1)
		{
		params->alpha = 0.3;
		Msg(0, "Initial aplha value is undefined, default value = %f", params->alpha);
		}
	if (params->length == -1)
		{
		params->length = 10000;
		Msg(0, "Learning iteration value is undefined, default value = %l", params->length);
		}

	LVQParamstoTeach(&tparams, params);					/*Initialize the teach_param struct*/
	
	pcode = lvq1_training(&tparams);
	
	if (pcode == NULL)
		return -1;
	
	delete params->pcode;
	params->pcode = NULL;
	ret = EntriestoMat(&(params->pcode), pcode);
	
	return ret;
	}


/***********************************************************************************************
* olvq1 : optimized-learning-rate LVQ1 algorithm, recomended for the main learning algorithm
* It must always be preceded by an initialization procedure, either eveninit or propinit, 
* and possibly by the program balance, too.
***********************************************************************************************/
int olvq1(PLVQPARAMS params)
	{
	int ret;
	struct teach_params tparams;
	struct entries *pcode;
	
	if (params->radius == -1)
		{
		params->radius = 90.0;
		Msg(0, "Radius is undefined, default value = %f", params->radius);
		}
	if (params->alpha == -1)
		{
		params->alpha = 0.3;
		Msg(0, "Initial aplha value is undefined, default value = %f", params->alpha);
		}
	if (params->length == -1)
		{
		params->length = 10000;
		Msg(0, "Learning iteration value is undefined, default value = %l", params->length);
		}

	LVQParamstoTeach(&tparams, params);					/*Initialize the teach_param struct*/
	
	pcode = olvq1_training(&tparams, NULL, NULL);
	
	if (pcode == NULL)
		return -1;
	
	delete params->pcode;
	params->pcode = NULL;
	ret = EntriestoMat(&(params->pcode), pcode);
	
	return ret;
	}

/***********************************************************************************************
* lvq2 : used for an additional fine tuning stage in learning (low alpha). 
* The relative length of the window parameter (winlen field of PLVQPARAMS), into which the 
* codebook vector must fall to get an updating, is used.
***********************************************************************************************/
int lvq2(PLVQPARAMS params)
	{
	int ret;
	struct teach_params tparams;
	struct entries *pcode;
	
	if (params->radius == -1)
		{
		params->radius = 90.0;
		Msg(0, "Radius is undefined, default value = %f", params->radius);
		}
	if (params->alpha == -1)
		{
		params->alpha = 0.3;
		Msg(0, "Initial aplha value is undefined, default value = %f", params->alpha);
		}
	if (params->length == -1)
		{
		params->length = 10000;
		Msg(0, "Learning iteration value is undefined, default value = %l", params->length);
		}
	if (params->winlen == -1)
		{
		params->winlen = 0.3;
		Msg(0, "Length of window for the LVQ2 or LVQ3 is undefined, default value = %f", params->winlen);
		}

	LVQParamstoTeach(&tparams, params);					/*Initialize the teach_param struct*/
	
	pcode = lvq2_training(&tparams, params->winlen);
	
	if (pcode == NULL)
		return -1;
	
	delete params->pcode;
	params->pcode = NULL;
	ret = EntriestoMat(&(params->pcode), pcode);
	
	return ret;
	}

/***********************************************************************************************
* lvq3 : used for an additional fine tuning stage in learning (low alpha). 
* The relative length of the window parameter (winlen field of PLVQPARAMS), into which the 
* codebook vector must fall to get an updating, is used.
* Here epsilon is used, too. It is the relative learning rate used when both of the nearest 
* codebook vectors belong to the same class.
***********************************************************************************************/
int lvq3(PLVQPARAMS params)
	{
	int ret;
	struct teach_params tparams;
	struct entries *pcode;
	
	if (params->radius == -1)
		{
		params->radius = 90.0;
		Msg(0, "Radius is undefined, default value = %f", params->radius);
		}
	if (params->alpha == -1)
		{
		params->alpha = 0.3;
		Msg(0, "Initial aplha value is undefined, default value = %f", params->alpha);
		}
	if (params->length == -1)
		{
		params->length = 10000;
		Msg(0, "Learning iteration value is undefined, default value = %l", params->length);
		}
	if (params->winlen == -1)
		{
		params->winlen = 0.3;
		Msg(0, "Length of window for the LVQ2 or LVQ3 is undefined, default value = %f", params->winlen);
		}
	if (params->epsilon == -1)
		{
		params->epsilon = 10;
		Msg(0, "Epsilon value for the LVQ3 is undefined, default value = %i", params->epsilon);
		}

	LVQParamstoTeach(&tparams, params);					/*Initialize the teach_param struct*/
	
	pcode = lvq3_training(&tparams, params->epsilon, params->winlen);
	
	if (pcode == NULL)
		return -1;
	
	delete params->pcode;
	params->pcode = NULL;
	ret = EntriestoMat(&(params->pcode), pcode);
	
	return ret;
	}

⌨️ 快捷键说明

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