manifold.cpp
来自「一个由Mike Gashler完成的机器学习方面的includes neural」· C++ 代码 · 共 1,682 行 · 第 1/5 页
CPP
1,682 行
for(y = 0; y < nImageHeight; y++)
{
for(x = 0; x < nImageWidth; x++)
{
col = m_pImages[i].GetPixel(x, y);
nGrayScaleValue = 77 * (int)gRed(col) + 150 * (int)gGreen(col) + 29 * (int)gBlue(col);
pVector[y * nImageWidth + x] = nGrayScaleValue;
}
}
}
if(bComputeIdeal)
{
m_pIdealResults = new double[m_pData->GetSize()];
m_pIdealResults[0] = 0;
double* pVec1;
double* pVec2;
int i;
for(i = 1; i < m_pData->GetSize(); i++)
{
pVec1 = m_pData->GetVector(i - 1);
pVec2 = m_pData->GetVector(i);
m_pIdealResults[i] = m_pIdealResults[i - 1] + sqrt(m_pRelation->ComputeInputDistanceSquared(pVec1, pVec2));
}
}
// Allocate and init the sculpter
m_pSculpter = new GManifoldSculpting(m_pData->GetSize(), m_pRelation->GetInputCount(), nNeighbors);
m_pSculpter->SetData(m_pRelation, m_pData);
m_pSculpter->SetSquishingRate(dSquishingRate);
m_pSculpter->SetSmoothingAdvantage(nSmoothingAdvantage);
m_pSculpter->SquishBegin(nTargetDims);
//printf("Total shortcuts: %d\n", m_pSculpter->CountShortcuts(nNeighbors * 2));
// Set the supervised points
if(nSupervisedPoints > 0)
{
for(i = 0; i < nSupervisedPoints; i++)
{
int nPoint = rand() % nImageCount;
m_pSculpter->SetVector(nPoint, pTrainedModel->GetSculpter()->GetVector(nPoint), false);
}
}
}
// Make the Isomap-faces model
ImageModel(const char* szFilename, int nDataPoints)
{
m_pImages = new GImage[ISOMAP_FACE_COUNT];
// open the file
FILE* pFile = fopen(szFilename, "r");
GAssert(pFile, "failed to open the file");
FileHolder hFile(pFile);
// Make a big buffer to hold a single line from the file
char* pBuf = new char[16384];
Holder<char*> hBuf(pBuf);
// Set the image sizes
int i;
for(i = 0; i < ISOMAP_FACE_COUNT; i++)
m_pImages[i].SetSize(ISOMAP_FACE_WIDTH, ISOMAP_FACE_HEIGHT);
// Prep the data
m_pRelation = new GArffRelation();
m_pData = new GArffData(nDataPoints);
for(i = 0; i < nDataPoints; i++)
m_pData->AddVector(new double[ISOMAP_FACE_WIDTH * ISOMAP_FACE_HEIGHT]);
// Load the data
int SampleRate = nDataPoints / ISOMAP_FACE_COUNT;
char* pData;
int brightness;
int d;
for(d = 0; d < ISOMAP_FACE_WIDTH * ISOMAP_FACE_HEIGHT; d++)
{
pData = fgets(pBuf, 16384, pFile);
GAssert(pData, "failed to read line");
if(!pData)
{
GAssert(false, "not enough data");
break;
}
for(i = 0; i < nDataPoints; i++)
{
while(*pData > '\0' && *pData <= ' ')
pData++;
double val = atof(pData);
m_pData->GetVector(i)[d] = val;
while(*pData > ' ')
pData++;
}
m_pRelation->AddAttribute(new GArffAttribute(true, 0, NULL));
for(i = 0; i < ISOMAP_FACE_COUNT; i++)
{
brightness = (int)(m_pData->GetVector(i * SampleRate)[d] * 255);
m_pImages[i].SetPixel(d / ISOMAP_FACE_WIDTH, d % ISOMAP_FACE_WIDTH, gARGB(0xff, brightness, brightness, brightness));
}
}
// Make the sculpter
int nNeighbors = ISOMAP_NEIGHBORS;
m_pSculpter = new GManifoldSculpting(m_pData->GetSize(), m_pRelation->GetInputCount(), nNeighbors);
m_pSculpter->SetData(m_pRelation, m_pData);
m_pSculpter->SetSquishingRate(.9995);
m_pSculpter->SetSmoothingAdvantage(10);
// Init the sculpter
printf("Computing metadata...\n");
double dStartTime = GTime::GetTime();
m_pSculpter->SquishBegin(/*nTargetDimensions*/ISOMAP_DIMS);
double dEndTime = GTime::GetTime();
printf("Time to compute metadata: %f\n", dEndTime - dStartTime);
}
virtual ~ImageModel()
{
delete[] m_pImages;
}
GImage* GetImage(int i)
{
return &m_pImages[i];
}
};
// -------------------------------------------------------------------------------
class SwissRollView : public ViewBase
{
protected:
GFloatRect m_viewRect, m_nextRect;
ManifoldModel* m_pModel;
public:
SwissRollView(ManifoldModel* pModel);
virtual ~SwissRollView();
void SetModel(ManifoldModel* pModel) { m_pModel = pModel; }
protected:
virtual void Draw(SDL_Surface *pScreen);
void DrawPoint(SDL_Surface *pScreen, int n);
};
SwissRollView::SwissRollView(ManifoldModel* pModel)
: ViewBase()
{
m_pModel = pModel;
// Set the view rect
m_nextRect.Set(-20, -15, 40, 30);
m_viewRect = m_nextRect;
}
SwissRollView::~SwissRollView()
{
}
void SwissRollView::DrawPoint(SDL_Surface *pScreen, int n)
{
// Draw the dot
double* pValues = m_pModel->GetPoint(n);
int x = (int)((pValues[0] - .3 * pValues[2] - m_viewRect.x) * m_screenRect.w / m_viewRect.w) + m_screenRect.x;
int y = (int)((pValues[1] + .5 * pValues[2] - m_viewRect.y) * m_screenRect.h / m_viewRect.h) + m_screenRect.y;
unsigned int col = (unsigned int)GetSpectrumColor((float)n / SWISS_ROLL_POINTS);
DrawDot(pScreen, x, y, col, /*(n % 200) == 0 ? 20 :*/ 5);
// Ajust the next rect
if(pValues[0] < m_nextRect.x)
{
m_nextRect.w += (m_nextRect.x - (float)pValues[0]);
m_nextRect.x = (float)pValues[0];
}
else if(pValues[0] > m_nextRect.x + m_nextRect.w)
m_nextRect.w = (float)pValues[0] - m_nextRect.x;
if(pValues[1] < m_nextRect.y)
{
m_nextRect.h += (m_nextRect.y - (float)pValues[1]);
m_nextRect.y = (float)pValues[1];
}
else if(pValues[1] > m_nextRect.y + m_nextRect.h)
m_nextRect.h = (float)pValues[1] - m_nextRect.y;
}
/*virtual*/ void SwissRollView::Draw(SDL_Surface *pScreen)
{
// Clear the screen
SDL_FillRect(pScreen, NULL/*&r*/, 0x000000);
//m_viewRect = m_nextRect;
m_viewRect.Set((m_viewRect.x * 4 + m_nextRect.x) / 5, (m_viewRect.y * 4 + m_nextRect.y) / 5, (m_viewRect.w * 4 + m_nextRect.w) / 5, (m_viewRect.h * 4 + m_nextRect.h) / 5);
// Reset the next rect
double* pValues = m_pModel->GetPoint(0);
m_nextRect.Set((float)pValues[0], (float)pValues[1], (float).000001, (float).000001);
// Plot the points in approximate order from back to front so it looks like we're
// clipping properly--this is a cheap hacky way to do clipping, but who cares?
int n;
/* for(n = (int)(SWISS_ROLL_POINTS * .225); n < SWISS_ROLL_POINTS / 2; n++)
DrawPoint(pScreen, n);
for(n = 0; n < (int)(SWISS_ROLL_POINTS * .225); n++)
DrawPoint(pScreen, n);
*/
for(n = 0/*SWISS_ROLL_POINTS / 2*/; n < SWISS_ROLL_POINTS; n++)
DrawPoint(pScreen, n);
// Add some border to the next rect and preserve aspect ratio
m_nextRect.x -= m_nextRect.w / 4;
m_nextRect.w += m_nextRect.w / 2;
m_nextRect.y -= m_nextRect.h / 4;
m_nextRect.h += m_nextRect.h / 2;
if(m_nextRect.h * 4 > m_nextRect.w * 3)
{
m_nextRect.x -= (m_nextRect.h * 4 / 3 - m_nextRect.w) / 2;
m_nextRect.w = m_nextRect.h * 4 / 3;
}
else
{
m_nextRect.y -= (m_nextRect.w * 3 / 4 - m_nextRect.h) / 2;
m_nextRect.h = m_nextRect.w * 3 / 4;
}
}
// -------------------------------------------------------------------------------
class ImageView : public ViewBase
{
public:
enum mode
{
FACES,
ISOMAP_FACES,
};
protected:
mode m_eMode;
GFloatRect m_viewRect, m_nextRect;
ImageModel* m_pModel;
public:
ImageView(ImageModel* pModel, mode eMode);
virtual ~ImageView();
protected:
virtual void Draw(SDL_Surface* pScreen);
void DrawFaceOneDim(SDL_Surface* pScreen, int n);
void DrawIsomapFace(SDL_Surface* pScreen, int n);
};
ImageView::ImageView(ImageModel* pModel, mode eMode)
: ViewBase()
{
m_eMode = eMode;
m_nextRect.Set(0, 0, 1, 1);
m_pModel = pModel;
}
ImageView::~ImageView()
{
}
void ImageView::DrawFaceOneDim(SDL_Surface* pScreen, int n)
{
// Draw the face
double* pValues = m_pModel->GetPoint(n);
float rowSize = m_viewRect.w / FACE_ROWS;
int row = (int)((pValues[0] - m_viewRect.x) / rowSize);
float column = (float)(pValues[0] - m_viewRect.x) - (row * rowSize);
int x = (int)(column * (m_screenRect.w - FACE_WIDTH) / rowSize) + m_screenRect.x;
unsigned int col = (unsigned int)GetSpectrumColor((float)n / FACE_COUNT);
int y = m_screenRect.y + FACE_HEIGHT + row * (m_screenRect.h - FACE_HEIGHT) / FACE_ROWS;
if(x >= 0 && y >= 0 && x < 800 - FACE_WIDTH && y < 600 - FACE_HEIGHT)
BlitImage(pScreen, x, y, m_pModel->GetImage(n));
// Ajust the next rect
if(pValues[0] < m_nextRect.x)
{
m_nextRect.w += (m_nextRect.x - (float)pValues[0]);
m_nextRect.x = (float)pValues[0];
}
else if(pValues[0] > m_nextRect.x + m_nextRect.w)
m_nextRect.w = (float)pValues[0] - m_nextRect.x;
}
void ImageView::DrawIsomapFace(SDL_Surface* pScreen, int n)
{
int SampleRate = m_pModel->GetPointCount() / ISOMAP_FACE_COUNT;
if((n % SampleRate) != 0)
return;
// Draw the face
double* pValues = m_pModel->GetPoint(n);
int x = (int)((pValues[ISOMAP_DIM_1] - m_viewRect.x) * m_screenRect.w / m_viewRect.w) + m_screenRect.x;
int y = (int)((pValues[ISOMAP_DIM_2] - m_viewRect.y) * m_screenRect.h / m_viewRect.h) + m_screenRect.y;
if(x >= 0 && y >= 0 && x < 800 - ISOMAP_FACE_WIDTH && y < 600 - ISOMAP_FACE_HEIGHT && n / SampleRate < ISOMAP_FACE_COUNT)
BlitImage(pScreen, x, y, m_pModel->GetImage(n / SampleRate));
// Ajust the next rect
if(pValues[ISOMAP_DIM_1] < m_nextRect.x)
{
m_nextRect.w += (m_nextRect.x - (float)pValues[ISOMAP_DIM_1]);
m_nextRect.x = (float)pValues[ISOMAP_DIM_1];
}
else if(pValues[ISOMAP_DIM_1] > m_nextRect.x + m_nextRect.w)
m_nextRect.w = (float)pValues[ISOMAP_DIM_1] - m_nextRect.x;
if(pValues[ISOMAP_DIM_2] < m_nextRect.y)
{
m_nextRect.h += (m_nextRect.y - (float)pValues[ISOMAP_DIM_2]);
m_nextRect.y = (float)pValues[ISOMAP_DIM_2];
}
else if(pValues[ISOMAP_DIM_2] > m_nextRect.y + m_nextRect.h)
m_nextRect.h = (float)pValues[ISOMAP_DIM_2] - m_nextRect.y;
}
/*virtual*/ void ImageView::Draw(SDL_Surface *pScreen)
{
// Clear the screen
SDL_FillRect(pScreen, NULL/*&r*/, 0x000000);
//m_viewRect.Set((m_viewRect.x * 4 + m_nextRect.x) / 5, (m_viewRect.y * 4 + m_nextRect.y) / 5, (m_viewRect.w * 4 + m_nextRect.w) / 5, (m_viewRect.h * 4 + m_nextRect.h) / 5);
m_viewRect = m_nextRect;
if(m_eMode == FACES)
{
// Reset the next rect
double* pValues = m_pModel->GetPoint(0);
m_nextRect.Set((float)pValues[0], 0, (float).000001, (float).000001);
// Plot the points
int n;
for(n = 0; n < FACE_COUNT; n++)
DrawFaceOneDim(pScreen, n);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?