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

📄 eveninit.cpp

📁 face recognition test source code
💻 CPP
字号:
/************************************************************************
 *                                                                      *
 *  Program package 'lvq_pak':                                          *
 *                                                                      *
 *  eveninit.c                                                          *
 *  -initializes the codebook entries evenly to all classes (eveninit)  *
 *   or with their numbers proportional to the data file (propinit)     *
 *                                                                      *
 *  Version 3.0                                                         *
 *  Date: 1 Mar 1995                                                    *
 *                                                                      *
 *  NOTE: This program package is copyrighted in the sense that it      *
 *  may be used for scientific purposes. The package as a whole, or     *
 *  parts thereof, cannot be included or used in any commercial         *
 *  application without written permission granted by its producents.   *
 *  No programs contained in this package may be copied for commercial  *
 *  distribution.                                                       *
 *                                                                      *
 *  All comments  concerning this program package may be sent to the    *
 *  e-mail address 'lvq@cochlea.hut.fi'.                                *
 *                                                                      *
 ************************************************************************/

#include "header.h"

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

#include <stdio.h>
#include <string.h>
#include "lvq_rout.h"
#include "tools.h"
#include <lvq.h>

static char *usage[] = {
  "eveninit/propinit - initializes the codebook. Eveninit initializes\n",
  " entries evenly to all classes, propinit with their numbers proportional\n",
  " to the data file. Initialzation type is determined from program name\n",
  " (eveninit or propinit) or is selected with the -type option.\n",
  "Required parameters:\n",
  "  -din filename         input data\n",
  "  -cout filename        output codebook filename\n",
  "  -noc integer          number of codebook vectors\n",
  "Optional parameters:\n",
  "  -init type            initialization type, eveninit or propinit. Overrides\n",
  "                        the type determined from the program name\n",
  "  -knn N                use N nearest neighbours\n", 
  "  -rand integer         seed for random number generator. 0 is current time\n",
  NULL};

struct entries *init_codes(long number_of_codes, struct entries *data,
			   int knn, int prop, WINNER_FUNCTION *find_knn)
	{
	long nol, tot, nic, emp, nom;
	struct data_entry *entr, *entr2, *temp, *d;
	struct entries *codebook;
	float frac, err;
	struct hitlist *classes;
	struct hit_entry *Class;
	eptr p;
	
	if ((codebook = copy_entries(data)) == NULL)
		return NULL;
	
	codebook->topol = TOPOL_LVQ;
	
	if ((classes = new_hitlist()) == NULL)
		return NULL;
	
	/* count number of classes in data */
	
	for (d = rewind_entries(data, &p); d != NULL; d = next_entry(&p))
		add_hit(classes, get_entry_label(d));
	
	nol = classes->entries;
	tot = data->num_entries;
	
	if (nol > number_of_codes) 
		{
		Msg(0, "There are more different classes than requested codes");
		}
	
	/* how many entries for each class */
	nic = number_of_codes / nol;
	
	ifverbose(2)
		Msg(0, "The codebook vectors for each class are picked");
	
	/* pick even number of codebook vectors for each class */
	for (Class = classes->head; Class != NULL; Class = Class->next)
		{
		if (prop)
			{
			Class->freq = Class->freq * (float) number_of_codes / tot;
			if (Class->freq < 1) 
				Class->freq = 1;
			}
		else
			Class->freq = nic;
		}
	
	entr = pick_inside_codes(classes, data, knn, find_knn);
	
	/* check if all required codebook vectors were found */
	emp = 0;
	for (Class = classes->head, emp = 0; Class != NULL; Class = Class->next)
		{
		if (Class->freq == 0)
			emp++;
		}
	
	ifverbose(2)
		Msg(0, "For %d classes all found", emp);
	
	temp = entr;
	nom = 0;
	while (temp != NULL) 
		{
		nom++;
		temp = temp->next;
		}
	ifverbose(2)
		Msg(0, "Found %d vectors in first pass", nom);
	
	if (nom < number_of_codes) 
		{
		frac = 0.0;
		err = 0.0;
		if (emp != 0)
			frac = (number_of_codes - nom) / (float) emp;
		
		for (Class = classes->head; Class != NULL; Class = Class->next)
			{
			if (Class->freq == 0) 
				{
				Class->freq = (int) (frac + err);
				err = frac + err - Class->freq;
				}
			else 
				Class->freq = 0;
			}
		    
		/* pick more codes from those classes where you got all */
		entr2 = pick_inside_codes(classes, data, knn, find_knn);
		    
		temp = entr;
		if (temp != NULL) 
			{
			while (temp->next != NULL) 
				{
				temp = temp->next;
				}
			temp->next = entr2;
			}
		else 
			{
			entr = entr2;
			}
		}
	
	free_hitlist(classes);
	codebook->entry = entr;
	
	temp = entr;
	while (temp != NULL) 
		{
		codebook->num_entries++;
		temp = temp->next;
		}
	codebook->num_loaded = codebook->num_entries;
	codebook->flags.totlen_known = 1;
	
	return(codebook);
	}

/*********************************************************************************************
* This function initialises evenly the codebook vectors.
*
* Its only parameter is a pointer to a LVQPARAMs struct
* This function requires : noc, knn, xdim, ydim, neigh, topol, randomize and pdata
* Its output is pcode.
*********************************************************************************************/
int eveninit(PLVQPARAMS params)
	{
	struct entries *pdata, *pcode;
	int ret;
	           
	init_random(params->randomize);
	
	ret = MattoEntries(&pdata, params->pdata);
	if (ret < 0)
		return ret;
	pdata->topol = params->topol;
	pdata->neigh = params->neigh;
	pdata->xdim = params->xdim;
	pdata->ydim = params->ydim;
		
	pcode = init_codes(params->noc, pdata, params->knn, 0, find_winner_knn);
	if (pcode == NULL)
		{
		Msg(0, "Failed to initialize codes");
		return -1;
		}
	
	DeleteEntries(pdata);

	params->pcode = NULL;
	ret = EntriestoMat(&(params->pcode), pcode);
	if (ret < 0)
		{
		DeleteEntries(pcode);
		return ret;
		}
	DeleteEntries(pcode);
	
	return 0;
	}

/*********************************************************************************************
* This function defines the number of codebook vectors for each class in proportion to the
* a priori probabilities of the classes.
*
* Its only parameter is a pointer to a LVQPARAMs struct
* This function requires : noc, knn, xdim, ydim, neigh, topol, randomize and pdata
* Its output is pcode.
*********************************************************************************************/
int propinit(PLVQPARAMS params)
	{
	struct entries *pdata, *pcode;
	int ret;
	           
	if (params->noc == -1)
		{
		params->noc = 9;
		Msg(0, "Number of codebook vector is undefined, default value = %i", params->noc);
		}
	if (params->knn < 1)
		{
		Msg(0, "knn is undefined, min euclidian dist classifier chosen");
		}
	if (params->xdim == -1)
		{
		params->xdim = 3;
		Msg(0, "xdim is undefined, default value = %i", params->xdim);
		}
	if (params->ydim == -1)
		{
		params->ydim = 3;
		Msg(0, "ydim is undefined, default value = %i", params->ydim);
		}
	if (params->neigh == NEIGH_UNKNOWN)
		{
		params->neigh = NEIGH_GAUSSIAN;
		Msg(0, "Neighborhood type is undefined, default value = Gaussian");
		}
	if (params->topol == TOPOL_UNKNOWN)
		{
		params->topol = TOPOL_RECT;
		Msg(0, "Topology of codebook vector is undefined, default value = Rect");
		}

	init_random(params->randomize);
	
	ret = MattoEntries(&pdata, params->pdata);
	if (ret < 0)
		return ret;
	pdata->topol = params->topol;
	pdata->neigh = params->neigh;
	pdata->xdim = params->xdim;
	pdata->ydim = params->ydim;
		
	pcode = init_codes(params->noc, pdata, params->knn, 1, find_winner_knn);
	if (pcode == NULL)
		{
		Msg(0, "Failed to initialize codes");
		return -1;
		}
	
	DeleteEntries(pdata);
	
	ret = EntriestoMat(&(params->pcode), pcode);
	if (ret < 0)
		{
		DeleteEntries(pcode);
		return ret;
		}
	DeleteEntries(pcode);
	
	return 0;
	}

⌨️ 快捷键说明

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