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 + -
显示快捷键?