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

📄 gmm.cpp

📁 一个遗传算法(GA)的实现。command line 的结构。输入输出格式请见命令行
💻 CPP
字号:
// GMM.cpp: implementation of the CGMM class.
//
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "GMM.h"

#define TAGNUM 15
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGMM::CGMM()
{
	bLoaded = false;
}


CGMM::~CGMM()
{
	FreeGMMSet();
}


//--------------------------------------------------------------
// Load GMM from the definition files
// RETURN VALUE:
//		0 : Fail
//		1 : 
int CGMM::LoadGMMSet(char *fname)
{
	char *cTags[TAGNUM] = {"BEGINHMM","ENDHMM","GCONST","MEAN","MIXTURE",
		"NULLD","NUMMIXES","NUMSTATES","STATE","STREAM",
		"STREAMINFO","SWEIGHTS","TRANSP","VARIANCE","VECSIZE"};
	char ch,cbuf[100];
	FILE *fp;
	int ii,ij,ibuf;
	int iCurStream=0 , iCurMixture=0;
	double fdete;
	bool bNUMMIXES = false;
	
	if ((fp=fopen(fname,"r"))==NULL)
	{
		printf(" *** Error in opening \"%s\"! ::: CGMM::LoadGMMSet()\n",fname);
		exit(-1);
	}

	while (!feof(fp))
	{
		ch=getc(fp);
		switch (ch) {
		case '~':
			ch=getc(fp);
			switch (ch) {
			case 'o':
				break;
			case 'h':
				fscanf(fp,"%s",inst.cname);
				break;
			default:
				printf(" *** Unknown MICRO in \"%s\"! ::: CGMM::LoadGMMSet()\n",fname);
				fclose(fp);return 0;
			}
			getc(fp);
			break;
		case '<':
			ii = 0;
			while ((cbuf[ii]=getc(fp))!='>' && ii<20) ii++;
			cbuf[ii]=0;
			if (ii>=20)
			{
				printf(" *** Too long TAG in \"%s\"! ::: CGMM::LoadGMMSet()\n",fname);
				fclose(fp);return 0;
			}
			for (ii=0;ii<TAGNUM;ii++) // TAGNUM = 15
			{
				if (strcmp(cbuf,cTags[ii])==0)
					break;
			}
			switch (ii) {
			case 10: // <STREAMINFO>
				fscanf(fp,"%d",&ibuf); // number of streams

				inst.iStreamInfo = new int[ibuf+1]; // alloc mem
				inst.iStreamInfo[0] = ibuf;
				for (ii=0;ii<ibuf;ii++)
					fscanf(fp,"%d",inst.iStreamInfo+ii+1);
				inst.iNumMixtures = new int[inst.iStreamInfo[0]];
				inst.dSWeights = new double[inst.iStreamInfo[0]];
				inst.dDet = new double*[inst.iStreamInfo[0]];
				inst.dMixtureWeight = new double*[inst.iStreamInfo[0]];
				inst.dMean = new double**[inst.iStreamInfo[0]];
				inst.dCovar = new double**[inst.iStreamInfo[0]];

				getc(fp);	// read the tailing '\n', begin a new line
				break;
			case 14: // <VECSIZE>
				fscanf(fp,"%d",&inst.iVectorSize);
				break;
			case 5: // <NULLD>
				ch = getc(fp);
				ii = 0;
				while ((cbuf[ii]=getc(fp))!='>' && ii<20) ii++;
				cbuf[ii]=0;
				if (ii>=20)
				{
					printf(" *** Too long TAG in \"%s\"! ::: CGMM::LoadGMMSet()\n",fname);
					fclose(fp);return 0;
				}
				strcpy(inst.cparm,cbuf); // read the parameter's type, such as <MFCC_E>
				getc(fp); // skip the '\n', begin a new line
				break;
			case 7 : // <NUMSTATES>
				fscanf(fp,"%d\n",&inst.iNumStates); // Must be 3 in a GMM
				if (inst.iNumStates!=3)
				{
					printf(" *** Not a GMM ! ::: CGMM::LoadGMMSet()\n",fname);
					fclose(fp);return 0;
				}
				break;
			case 8: // <STATE>
				fscanf(fp,"%d\n",&ibuf);
				break;
			case 6: // <NUMMIXES>
				for (ii=0;ii<inst.iStreamInfo[0];ii++)
				{	// for each stream
					fscanf(fp,"%d",inst.iNumMixtures+ii);
					inst.dDet[ii] = new double[inst.iNumMixtures[ii]];
					inst.dMixtureWeight[ii] = new double[inst.iNumMixtures[ii]];
					inst.dMean[ii] = new double*[inst.iNumMixtures[ii]];
					for (ij=0;ij<inst.iNumMixtures[ii];ij++) // for each mixture in every streams
						inst.dMean[ii][ij] = new double[inst.iStreamInfo[ii+1]];
					inst.dCovar[ii] = new double*[inst.iNumMixtures[ii]];
					for (ij=0;ij<inst.iNumMixtures[ii];ij++) // for each misture in every streams
						inst.dCovar[ii][ij] = new double[inst.iStreamInfo[ii+1]];
				}
				bNUMMIXES = true;
				getc(fp);
				break;
			case 11: // <SWEIGHTS>
				fscanf(fp,"%d\n",&ibuf);
//				ASSERT(ibuf==inst.iStreamInfo[0]);
				for (ii=0;ii<ibuf;ii++)
					fscanf(fp,"%lf",&inst.dSWeights[ii]);
				getc(fp);
				break;
			case 9: // <STREAM>
				fscanf(fp,"%d\n",&iCurStream); // current stream
				iCurStream--;
				break;
			case 4: // <MIXTURE>
				fscanf(fp,"%d",&iCurMixture); // current mixture
				iCurMixture--;
				fscanf(fp,"%lf\n",&inst.dMixtureWeight[iCurStream][iCurMixture]);
				break;
			case 3: // <MEAN>
				if (!bNUMMIXES)
				{ // if there is no NUMMIXES tag (then no MIXTURE tags)
					for (ii=0;ii<inst.iStreamInfo[0];ii++)
					{	// for each stream
						inst.iNumMixtures[ii] = 1;
						inst.dDet[ii] = new double[inst.iNumMixtures[ii]];
						inst.dMixtureWeight[ii] = new double[inst.iNumMixtures[ii]];
						inst.dMixtureWeight[ii][0] = 1;
						inst.dMean[ii] = new double*[inst.iNumMixtures[ii]];
						for (ij=0;ij<inst.iNumMixtures[ii];ij++) // for each mixture in every streams
							inst.dMean[ii][ij] = new double[inst.iStreamInfo[ii+1]];
						inst.dCovar[ii] = new double*[inst.iNumMixtures[ii]];
						for (ij=0;ij<inst.iNumMixtures[ii];ij++) // for each misture in every streams
							inst.dCovar[ii][ij] = new double[inst.iStreamInfo[ii+1]];
					}
				}

				fscanf(fp,"%d\n",&ibuf);
//				ASSERT(ibuf==inst.iStreamInfo[iCurStream+1]);
				for (ii=0;ii<ibuf;ii++)
					fscanf(fp,"%lf",&inst.dMean[iCurStream][iCurMixture][ii]);
				getc(fp);
				break;
			case 13: // <VARIANCE>
				fscanf(fp,"%d\n",&ibuf);
//				ASSERT(ibuf==inst.iStreamInfo[iCurStream+1]);
				for (fdete=1,ii=0;ii<ibuf;ii++)
				{
					fscanf(fp,"%lf",&inst.dCovar[iCurStream][iCurMixture][ii]);
					fdete *= inst.dCovar[iCurStream][iCurMixture][ii];
				}
				inst.dDet[iCurStream][iCurMixture] = fdete;
				getc(fp);
				break;
			case 2:
			case 1:
			case 0:
			case 12: // <GCONST>,<BEGINHMM>,<ENDHMM>,<TRANSP>
				while((ch=getc(fp))!=10 && !feof(fp))
					;
				break;
			default:
				printf(" *** Unknown <TAG> ! ::: CGMM::LoadGMMSet()\n",fname);
				fclose(fp);return 0;
			}
		default: ; // not begin with '~' or '<', skipping
		}
	}

	fclose(fp);
	bLoaded = true;


	// Test output
	int ik;
	fp = fopen("output","w");
	fprintf(fp,"~o\n<STREAMINFO> %d",inst.iStreamInfo[0]);
	for (ii=0;ii<inst.iStreamInfo[0];ii++)
		fprintf(fp," %d",inst.iStreamInfo[ii+1]);
	fprintf(fp,"\n");
	fprintf(fp,"<VECTERSIZE> %d<NULLD><%s>\n",inst.iVectorSize,inst.cparm);
	fprintf(fp,"~h \"%s\"",inst.cname);
	fprintf(fp,"<NUMSTATES> %d\n<NUMMIXES>",inst.iNumStates);
	for (ii=0;ii<inst.iStreamInfo[0];ii++)
		fprintf(fp," %d",inst.iNumMixtures[ii]);
	fprintf(fp,"\n<SWEIGHTS> %d\n",inst.iStreamInfo[0]);
	for (ii=0;ii<inst.iStreamInfo[0];ii++)
		fprintf(fp," %f",inst.dSWeights[ii]);
	fprintf(fp,"\n");
	for (ii=0;ii<inst.iStreamInfo[0];ii++)
	{
		fprintf(fp,"<STREAM> %d\n",ii);
		for (ij=0;ij<inst.iNumMixtures[ii];ij++)
		{
			fprintf(fp,"<MIXTURE> %d %f\n",ij,inst.dMixtureWeight[ii][ij]);
			fprintf(fp,"<MEAN> %d\n",inst.iStreamInfo[ii+1]);
			for (ik=0;ik<inst.iStreamInfo[ii+1];ik++)
				fprintf(fp," %f",inst.dMean[ii][ij][ik]);
			fprintf(fp,"\n<VARIANCE> %d\n",inst.iStreamInfo[ii+1]);
			for (ik=0;ik<inst.iStreamInfo[ii+1];ik++)
				fprintf(fp," %f",inst.dCovar[ii][ij][ik]);
			fprintf(fp,"\n");
		}
	}
	fprintf(fp,"<ENDHMM>\n");
	fclose(fp);

	return 1;
}


//--------------------------------------------------------------
// Free memory before exit
int CGMM::FreeGMMSet()
{
	int ii,ij;

	if (!bLoaded)
		return 0;
	for (ii=0;ii<inst.iStreamInfo[0];ii++)
	{ // for each stream
		for (ij=0;ij<inst.iNumMixtures[ii];ij++)
		{ // for each mixture
			delete[] inst.dMean[ii][ij];
			delete[] inst.dCovar[ii][ij];
		}
		delete[] inst.dMean[ii];
		delete[] inst.dCovar[ii];
		delete[] inst.dDet[ii];
		delete[] inst.dMixtureWeight[ii];
	}
	delete[] inst.dMean;
	delete[] inst.dCovar;
	delete[] inst.dDet;
	delete[] inst.dMixtureWeight;
	delete[] inst.iNumMixtures;
	delete[] inst.dSWeights;
	delete[] inst.iStreamInfo;
	
	bLoaded = false;
	return 1;
}


//---------------------------------------------------------------
// Calculate the output probility of the given dimension
// Scale : input value
// idx   : absolute index
// dresult : buffer for prob of each mixture
// imix  : length of the dresult, should be equal to the mixture
//             of the given stream
int CGMM::LScaleProb(double Scale,int idx,double *dresult,int imix)
{
	int ii,is,iv;
	double dsqrt2pai = 2.506628275; // sqrt (2 * PAI)
	double dexp,fcoe;

	if (!bLoaded || idx>inst.iVectorSize)
		return 0;
	for (ii=0;ii<inst.iStreamInfo[0];ii++)
	{
		if (idx < inst.iStreamInfo[ii+1])
			break;
		idx -= inst.iStreamInfo[ii+1];
	}
	is = ii; iv = idx;

	if (imix!=inst.iNumMixtures[is])
		return 0;

	for (ii=0;ii<imix;ii++)
	{
		fcoe = dsqrt2pai * sqrt(inst.dCovar[is][ii][iv]);
		dexp = exp(-0.5 * (Scale-inst.dMean[is][ii][iv])*(Scale-inst.dMean[is][ii][iv])/inst.dCovar[is][ii][iv]);
		dresult[ii] = inst.dMixtureWeight[is][ii] * dexp / fcoe;
	}
	return 1;
}


int CGMM::LScaleProb(double Scale,int istrm,int idx,double *fresult)
{
	int ii;
	double dsqrt2pai = 2.506628275; // sqrt (2 * PAI)
	const double dlog2pai = 1.837877066; // log(2*pai)
	double dcoe,dtmp;

	if (!bLoaded)
		return 0;

	*fresult = 0;
	for (ii=0;ii<inst.iNumMixtures[istrm];ii++)
	{
		dtmp = Scale-inst.dMean[istrm][ii][idx];
		dtmp *= dtmp;
		dcoe = - dlog2pai - log(inst.dCovar[istrm][ii][idx]) - dtmp/inst.dCovar[istrm][ii][idx];
		dcoe = inst.dMixtureWeight[istrm][ii] * exp(dcoe/2);
		*fresult += (float)dcoe;
	}
	*fresult = log(*fresult);
	return 1;
}


//---------------------------------------------------------------
// Calculate the output probility of the given vector according
//   to the Triggers (Enable or disable particular dimensions)
// ONLY SUPPORT ONE STREAM NOW !!
double CGMM::LVectorProb(float *Feature_Vector,int *Trigger_Vector)
{
	int ii,ij,isum;
	double dresult,dsum,ddet,dtmp;
	double dlog2pai = 1.837877066;

	if (!bLoaded)
		return 0.0;

	dresult = 0.0;
	for (ii=0;ii<inst.iNumMixtures[0];ii++) // !!!
	{ // for each mixture
		isum = 0;	// number of valid values
		dsum = 0.0;	// 
		ddet = 1.0;	// deltermination
		// only ONE stream !!
		for (ij=0;ij<inst.iStreamInfo[1];ij++)
		{	// for each value of a frame
			if (Trigger_Vector[ij])
			{	// if valid
				dtmp = Feature_Vector[ij] - inst.dMean[0][ii][ij];
				dtmp = dtmp * dtmp;
				dsum += dtmp / inst.dCovar[0][ii][ij];
				isum ++;
				ddet *= inst.dCovar[0][ii][ij];
			}
		}
		dsum = - isum*dlog2pai - log(ddet) - dsum;
		dsum = exp(dsum/2);
//		dsum = exp(-0.5 * dsum) / sqrt(pow(d2pai,isum)*ddet);
		dresult += inst.dMixtureWeight[0][ii] * dsum;
	}
	return (log(dresult));
}

⌨️ 快捷键说明

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