int pkmGaussianMixtureModel::writeToFile(ofstream &fileStream, bool writeClusterNums, bool writeWeights, bool writeMeans, bool writeCovs, bool verbose)
{
	if(!fileStream.is_open())
		return -1;
	
	// use the best-model 
	CvEM myModel = emModel[bestModel];
	const CvMat **modelCovs = myModel.get_covs();
	const CvMat *modelMus = myModel.get_means();
	const CvMat *modelWeights = myModel.get_weights();
	int numClusters = myModel.get_nclusters();
	
	// output the total number of clusters
	if(writeClusterNums)
	{
		if(verbose)
			fileStream << "Number of Clusters: " << numClusters << "\n";
		else
			fileStream << numClusters << "\n";
	}
	
	if(writeWeights)
	{
		// output the weights of each cluster
		if(verbose)
			fileStream << "Weight of Clusters\n";
		for (int k = 0; k < numClusters; k++)
		{
			const double *weightPtr = (const double *)(modelWeights->data.ptr + k*modelWeights->step);
			double weight = weightPtr[0];
			if(verbose)
				fileStream << k << ": " << weight << "\n";
			else
				fileStream << weight << " ";
		}
		fileStream << "\n";
	}
	
	if(writeMeans)
	{
		// output the means of each cluster
		if(verbose)
			fileStream << "Means of Clusters\n";
		for (int k = 0; k < numClusters; k++)
		{
			if(verbose)
				fileStream << "Cluster " << k << ":\n";
			for (int i = 0; i < m_nVariables; i++)
			{
				if(verbose)
					fileStream << i << ": " << cvmGet(modelMus, k, i) << " ";
				else
					fileStream << cvmGet(modelMus, k, i) << " ";
			}
			fileStream << "\n";
		}
	}
	
	if(writeCovs)
	{
		// output the covariances of each cluster
		if(verbose)
			fileStream << "Covariances of Clusters\n";
		for (int k = 0; k < numClusters; k++)
		{
			const CvMat * covar = modelCovs[k];
			if(verbose)
				fileStream << "Cluster " << k << ":\n";
			for (int i = 0; i < m_nVariables; i++)
			{
				for (int j = 0; j < m_nVariables; j++)
				{
					if(verbose)
						fileStream << i << "," << j << ": " << cvmGet(covar, i, j) << " ";
					else
						fileStream << cvmGet(covar, i, j) << " ";
				}
			}
			fileStream << "\n";
		}
	}
	return 0;
}
/*void pkmGaussianMixtureModel::getLikelihood(int x, int y)
 {
 
 }
 */
void pkmGaussianMixtureModel::getLikelihoodMap(int rows, int cols, unsigned char *map, ofstream &filePtr, int widthstep)
{
	if(widthstep == 0)
        widthstep = cols;
 
    if(!bModeled)
        return;
    
	CvEM myModel = emModel[bestModel];
	const CvMat **modelCovs = myModel.get_covs();
	const CvMat *modelMus = myModel.get_means();
	const CvMat *modelWeights = myModel.get_weights();
	int numClusters = myModel.get_nclusters();
	CvMat *pts = cvCreateMat(m_nVariables, 1, CV_64FC1);
	CvMat *mean = cvCreateMat(m_nVariables, 1, CV_64FC1);
	
	double p = 0;
	double weight;
	double max = 0;
	double prob;
	filePtr << "clusters: " << numClusters << "\n";
	filePtr << "likelihood: " << m_Likelihood << "\n";
	filePtr << "BIC: " << m_BIC << "\n";
	//printf("clusters: %d\n", numClusters);
	
    float best_weight = 0;
    bestCluster = 0;
    
	for (int k = 0; k < numClusters; k++)
	{
		const CvMat * covar = modelCovs[k];
		//printf("covar: (%f, %f, %f, %f)\n", covar->data.ptr[0], \
		covar->data.ptr[1], \
		covar->data.ptr[2], \
		covar->data.ptr[3]);
		//const double *meanVals = (const double *)(modelMus->data.ptr + k*modelWeights->step);
		
		cvmSet(mean, 0, 0, cvmGet(modelMus, k, 0));
		cvmSet(mean, 1, 0, cvmGet(modelMus, k, 1));
		
		//const double *weightPtr = (const double *)(modelWeights->data.ptr + k*modelWeights->step);
		//weight = weightPtr[k];
		weight = cvmGet(modelWeights, 0, k);
        
        if (best_weight < weight) {
            best_weight = weight;
            bestCluster = k;
        }
		
		filePtr << "mean: " << cvmGet(modelMus, k, 0)*(double)m_nScale << " " << cvmGet(modelMus, k, 1)*(double)m_nScale << "\n";
		
		filePtr << "covar: " << cvmGet(covar, 0, 0) << "\n";
		
		filePtr << "weight: " << weight << "\n";
		
		for (int i = 0; i < rows; i++)
		{
			for (int j = 0; j < cols; j++)
			{
				cvmSet(pts, 0, 0, (double)j);
				cvmSet(pts, 1, 0, (double)i);	
				prob = multinormalDistribution(pts, mean, covar);
				map[j+i*widthstep] += (int)((weight * prob)*(double)(rows*cols));				
				
			}
		}
	}
	cvReleaseMat(&mean);
	cvReleaseMat(&pts);
}