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