manifold.cpp

来自「一个由Mike Gashler完成的机器学习方面的includes neural」· C++ 代码 · 共 1,682 行 · 第 1/5 页

CPP
1,682
字号
// --------------------------------------------------------
// This demo file is dedicated to the Public Domain. See:
// http://creativecommons.org/licenses/publicdomain
// --------------------------------------------------------

#include "Manifold.h"
#include "../GClasses/GManifold.h"
#include "../GClasses/GArff.h"
#include "../GClasses/GBits.h"
#include "../GClasses/GFile.h"
#include "../GClasses/GTime.h"
#include "../GClasses/GThread.h"
#include "../GClasses/GVector.h"
#include "../GClasses/GMath.h"
#include "../GClasses/GGreedySearch.h"
#include <math.h>

#define SWISS_ROLL_POINTS 2000

#define FACE_WIDTH 43
#define FACE_HEIGHT 38
#define FACE_COUNT 50
#define FACE_ROWS 5
#define FACE_NEIGHBORS 6

#define ISOMAP_FACE_WIDTH 64
#define ISOMAP_FACE_HEIGHT 64
#define ISOMAP_FACE_COUNT 75
#define ISOMAP_DIMS 2
#define ISOMAP_DIM_1 0
#define ISOMAP_DIM_2 1
#define ISOMAP_NEIGHBORS 2

class ManifoldModel;

class Compute2DErrorCritic : public GRealVectorCritic
{
protected:
	ManifoldModel* m_pModel;

public:
	Compute2DErrorCritic(ManifoldModel* pModel) : GRealVectorCritic(5)
	{
		m_pModel = pModel;
	}

	virtual ~Compute2DErrorCritic()
	{
	}

	virtual double ComputeError(double* pVector);
};

class Compute1DErrorCritic : public GRealVectorCritic
{
protected:
	ManifoldModel* m_pModel;

public:
	Compute1DErrorCritic(ManifoldModel* pModel) : GRealVectorCritic(2)
	{
		m_pModel = pModel;
	}

	virtual ~Compute1DErrorCritic()
	{
	}

	virtual double ComputeError(double* pVector);
};



class ManifoldModel
{
protected:
	GArffRelation* m_pRelation;
	GArffData* m_pData;
	GManifoldSculpting* m_pSculpter;
	double* m_pIdealResults;

public:
	ManifoldModel()
	{
		m_pRelation = NULL;
		m_pData = NULL;
		m_pSculpter = NULL;
		m_pIdealResults = NULL;
		srand(0); // arbitrary value so we always get consistent results
	}

	virtual ~ManifoldModel()
	{
		delete(m_pSculpter);
		delete(m_pData);
		delete(m_pRelation);
		delete[] m_pIdealResults;
	}

	double* GetPoint(int n)
	{
		return m_pSculpter->GetVector(n);
	}

	int GetPointCount()
	{
		return m_pSculpter->GetDataPointCount();
	}

	GManifoldSculpting* GetSculpter()
	{
		return m_pSculpter;
	}

	void ToMatrix(const char* szFilename)
	{
		FILE* pFile = fopen(szFilename, "w");
		GAssert(pFile, "failed to create file");
		int nDataPoints = m_pData->GetSize();
		int dim, n;
		for(dim = 0; dim < m_pRelation->GetInputCount(); dim++)
		{
			for(n = 0; n < nDataPoints; n++)
			{
				if(n > 0)
					fprintf(pFile, "\t");
				fprintf(pFile, "%f", m_pSculpter->GetVector(n)[dim]);
			}
			fprintf(pFile, "\n");
		}
		fclose(pFile);
	}

	void FromMatrix(const char* szFilename, int nTargetDimensions)
	{
		FILE* pFile = fopen(szFilename, "r");
		GAssert(pFile, "failed to open the file");
		FileHolder hFile(pFile);
		int nDataPoints = m_pData->GetSize();
		char* pBuf = new char[nDataPoints * 20];
		Holder<char*> hLine(pBuf);
		char* pData;
		int d;
		for(d = 0; d < nTargetDimensions; d++)
		{
			pData = fgets(pBuf, nDataPoints * 20, pFile);
			GAssert(pData, "failed to read line");
			if(!pData)
				break;
			int i;
			for(i = 0; i < nDataPoints; i++)
			{
				while(*pData > '\0' && *pData <= ' ')
					pData++;
				double val = atof(pData);
				m_pSculpter->GetVector(i)[d] = val;
				while(*pData > ' ')
					pData++;
			}
		}
		int i;
		for(i = 0; i < nDataPoints; i++)
		{
			m_pSculpter->GetVector(i)[2] = 0;
		}
	}

	int MeasureSingleDimOrderErrors()
	{
/*
		int nPos = 0;
		int nNeg = 0;
		int i;
		int nCount = m_pSculpter->GetDataPointCount();
		double* pVec1;
		double* pVec2;
		for(i = 1; i < nCount; i++)
		{
			pVec1 = m_pSculpter->GetVector(i - 1);
			pVec2 = m_pSculpter->GetVector(i);
			if(pVec1[0] > pVec2[0])
				nPos++;
			else if(pVec1[0] < pVec2[0])
				nNeg++;
		}
		return MIN(nNeg, nPos);
*/

		int nErrors = 0;
		int i;
		int nCount = m_pSculpter->GetDataPointCount();
		double* pVec1 = m_pSculpter->GetVector(0);
		double* pVec2 = m_pSculpter->GetVector(1);
		int nPrevSign = GBits::GetSign(pVec2[0] - pVec1[0]);
		int nSign;
		for(i = 2; i < nCount; i++)
		{
			pVec1 = m_pSculpter->GetVector(i - 1);
			pVec2 = m_pSculpter->GetVector(i);
			nSign = GBits::GetSign(pVec2[0] - pVec1[0]);
			if(nSign != nPrevSign)
			{
				nErrors++;
				nPrevSign = nSign;
			}
		}
		return nErrors;

	}

	void DoLLE(int nNeighbors)
	{
/*m_pRelation = new GArffRelation();
m_pRelation->AddAttribute(new GArffAttribute(true, 0, NULL));
m_pRelation->AddAttribute(new GArffAttribute(true, 0, NULL));
m_pData->DropAllVectors();
double* pVec;
pVec = new double[2];	pVec[0] = -20;	pVec[1] = -8;	m_pData->AddVector(pVec);
pVec = new double[2];	pVec[0] = -10;	pVec[1] = -1;	m_pData->AddVector(pVec);
pVec = new double[2];	pVec[0] = 0.00001;	pVec[1] = 0.00001;	m_pData->AddVector(pVec);
pVec = new double[2];	pVec[0] = 10;	pVec[1] = 1;	m_pData->AddVector(pVec);
pVec = new double[2];	pVec[0] = 20;	pVec[1] = 8;	m_pData->AddVector(pVec);
nNeighbors = 2;*/
		
		GArffData* pOldData = m_pData;
		m_pData = GLLE::DoLLE(m_pRelation, pOldData, nNeighbors);
		delete(pOldData);
		m_pSculpter->SetData(m_pRelation, m_pData);
	}

	double Compute2DError(double dRotation, double dXScale, double dYScale, double dX, double dY)
	{
		// Compute the mean
		int i;
		int nPointCount = m_pSculpter->GetDataPointCount();
		double* pVec;
		double mean[2];
		mean[0] = 0;
		mean[1] = 0;
		for(i = 0; i < nPointCount; i++)
		{
			pVec = m_pSculpter->GetVector(i);
			mean[0] += pVec[0];
			mean[1] += pVec[1];
		}
		mean[0] /= nPointCount;
		mean[1] /= nPointCount;

		// Compute the error
		double* pIdeal;
		double d, t;
		double vec[2];
		double dError = 0;
		for(i = 0; i < nPointCount; i++)
		{
			pVec = m_pSculpter->GetVector(i);
			pVec[0] -= mean[0];
			pVec[1] -= mean[1];
			d = sqrt(GVector::ComputeSquaredMagnitude(pVec, 2));
			t = atan2(pVec[1], pVec[0]);
			pVec[0] += mean[0];
			pVec[1] += mean[1];
			t += dRotation;
			vec[0] = d * cos(t) * dXScale + mean[0] + dX;
			vec[1] = d * sin(t) * dYScale + mean[1] + dY;
			pIdeal = &m_pIdealResults[2 * i];
			dError += GVector::ComputeSquaredDistance(vec, pIdeal, 2);
		}
		return dError / nPointCount;
	}

	double Measure2DError()
	{
		GAssert(m_pIdealResults, "ideal results were not computed");
		Compute2DErrorCritic critic(this);
		GMomentumGreedySearch searcher(&critic);
/*		double dInitVec[5];
		dInitVec[0] = GBits::GetRandomDouble() * 6.283; // rotation
		dInitVec[1] = GBits::GetRandomDouble(); // x-scale
		dInitVec[2] = GBits::GetRandomDouble(); // y-scale
		dInitVec[3] = GBits::GetRandomDouble() - .5; // x-translate
		dInitVec[4] = GBits::GetRandomDouble() - .5; // y-translate
		searcher.SetState(dInitVec);
		searcher.SetAllStepSizes(.0001);*/
		int i = 0;
		double dBest = 1e200;
		double d;
		while(true)
		{
			searcher.Iterate();
			d = critic.GetBestError();
			if(d < dBest)
			{
				dBest = d;
				i = 0;
			}
			else
			{
				i++;
				if(i > 1000)
					break;
			}
			//printf("Error: %f\n", d);
		}
		double* pBestVec = critic.GetBestYet();
		printf("Rot=%f, XScale=%f, YScale=%f, X=%f, Y=%f\n", pBestVec[0], pBestVec[1], pBestVec[2], pBestVec[3], pBestVec[4]);
		return critic.GetBestError();
	}

	virtual double Compute1DError(double dScale, double dAdd)
	{
		// Compute the error
		int i;
		int nPointCount = m_pSculpter->GetDataPointCount();
		double* pVec;
		double dIdeal, d;
		double dError = 0;
		for(i = 0; i < nPointCount; i++)
		{
			dIdeal = m_pIdealResults[i];
			pVec = m_pSculpter->GetVector(i);
			d = dIdeal - (pVec[0] * dScale + dAdd);
			dError += (d * d);
		}
		return dError / nPointCount;
	}

	double Measure1DError()
	{
		GAssert(m_pIdealResults, "ideal results were not computed");
		Compute1DErrorCritic critic(this);
		GMomentumGreedySearch searcher(&critic);
		int i = 0;
		double dBest = 1e200;
		double d;
		while(true)
		{

⌨️ 快捷键说明

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