<commit_before>/*
 * HLLib
 * Copyright (C) 2006-2010 Ryan Gregg

 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later
 * version.
 */

#include "HLLib.h"
#include "BSPFile.h"
#include "Streams.h"

using namespace HLLib;

#define HL_BSP_LUMP_ENTITIES		0
#define HL_BSP_LUMP_TEXTUREDATA		2
#define HL_BSP_MIPMAP_COUNT			4

const char *CBSPFile::lpAttributeNames[] = { "Version" };
const char *CBSPFile::lpItemAttributeNames[] = { "Width", "Height", "Palette Entries" };

CBSPFile::CBSPFile() : CPackage(), pHeaderView(0), pTextureView(0), pHeader(0), pTextureHeader(0)
{

}

CBSPFile::~CBSPFile()
{
	this->Close();
}

HLPackageType CBSPFile::GetType() const
{
	return HL_PACKAGE_BSP;
}

const hlChar *CBSPFile::GetExtension() const
{
	return "bsp";
}

const hlChar *CBSPFile::GetDescription() const
{
	return "Half-Life Level";
}

hlBool CBSPFile::MapDataStructures()
{
	if(sizeof(BSPHeader) > this->pMapping->GetMappingSize())
	{
		LastError.SetErrorMessage("Invalid file: the file map is too small for it's header.");
		return hlFalse;
	}

	if(!this->pMapping->Map(this->pHeaderView, 0, sizeof(BSPHeader)))
	{
		return hlFalse;
	}
	this->pHeader = static_cast<const BSPHeader *>(this->pHeaderView->GetView());

	if(this->pHeader->uiVersion != 30)
	{
		LastError.SetErrorMessageFormated("Invalid BSP version (v%u): you have a version of a BSP file that HLLib does not know how to read. Check for product updates.", this->pHeader->uiVersion);
		return hlFalse;
	}

	if(!this->pMapping->Map(this->pTextureView, this->pHeader->lpLumps[HL_BSP_LUMP_TEXTUREDATA].uiOffset, this->pHeader->lpLumps[HL_BSP_LUMP_TEXTUREDATA].uiLength))
	{
		return hlFalse;
	}
	this->pTextureHeader = static_cast<const BSPTextureHeader *>(this->pTextureView->GetView());

	return hlTrue;
}

hlVoid CBSPFile::UnmapDataStructures()
{
	this->pTextureHeader = 0;
	this->pMapping->Unmap(this->pTextureView);

	this->pHeader = 0;
	this->pMapping->Unmap(this->pHeaderView);
}

CDirectoryFolder *CBSPFile::CreateRoot()
{
	CDirectoryFolder *pRoot = new CDirectoryFolder(this);

	hlChar lpFileName[256];

	if(this->pHeader->lpLumps[HL_BSP_LUMP_ENTITIES].uiLength != 0)
	{
		this->GetFileName(lpFileName, sizeof(lpFileName) - 4);
		if(*lpFileName == '\0')
		{
			pRoot->AddFile("entities.ent", this->pTextureHeader->uiTextureCount);
		}
		else
		{
			strcat(lpFileName, ".ent");
			pRoot->AddFile(lpFileName, this->pTextureHeader->uiTextureCount);
		}
	}

	// Loop through each texture in the BSP file.
	for(hlUInt i = 0; i < this->pTextureHeader->uiTextureCount; i++)
	{
		if(this->pTextureHeader->lpOffsets[i] == -1)
		{
			continue;
		}

		const BSPTexture *pTexture = (const BSPTexture *)((const hlByte *)this->pTextureHeader + this->pTextureHeader->lpOffsets[i]);

		if(pTexture->lpOffsets[0] == 0)
		{
			continue;
		}

		sprintf(lpFileName, "%s.bmp", pTexture->lpName);

		// Add the lump as a bitmap.
		pRoot->AddFile(lpFileName, i);
	}

	return pRoot;
}

hlUInt CBSPFile::GetAttributeCountInternal() const
{
	return HL_BSP_PACKAGE_COUNT;
}

const hlChar *CBSPFile::GetAttributeNameInternal(HLPackageAttribute eAttribute) const
{
	if(eAttribute < HL_BSP_PACKAGE_COUNT)
	{
		return this->lpAttributeNames[eAttribute];
	}

	return 0;
}

hlBool CBSPFile::GetAttributeInternal(HLPackageAttribute eAttribute, HLAttribute &Attribute) const
{
	switch(eAttribute)
	{
	case HL_BSP_PACKAGE_VERSION:
		hlAttributeSetUnsignedInteger(&Attribute, this->lpAttributeNames[eAttribute], this->pHeader->uiVersion, hlFalse);
		return hlTrue;
	default:
		return hlFalse;
	}
}

hlUInt CBSPFile::GetItemAttributeCountInternal() const
{
	return HL_BSP_ITEM_COUNT;
}

const hlChar *CBSPFile::GetItemAttributeNameInternal(HLPackageAttribute eAttribute) const
{
	if(eAttribute < HL_BSP_ITEM_COUNT)
	{
		return this->lpItemAttributeNames[eAttribute];
	}

	return 0;
}

hlBool CBSPFile::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
{
	switch(pItem->GetType())
	{
		case HL_ITEM_FILE:
		{
			const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
			if(pFile->GetID() < this->pTextureHeader->uiTextureCount)
			{
				switch(eAttribute)
				{
					case HL_BSP_ITEM_WIDTH:
					{
						hlUInt uiWidth = 0, uiHeight = 0, uiPaletteSize = 0;
						this->GetLumpInfo(*pFile, uiWidth, uiHeight, uiPaletteSize, hlFalse);
						hlAttributeSetUnsignedInteger(&Attribute, this->lpItemAttributeNames[eAttribute], uiWidth, hlFalse);
						return hlTrue;
					}
					case HL_BSP_ITEM_HEIGHT:
					{
						hlUInt uiWidth = 0, uiHeight = 0, uiPaletteSize = 0;
						this->GetLumpInfo(*pFile, uiWidth, uiHeight, uiPaletteSize, hlFalse);
						hlAttributeSetUnsignedInteger(&Attribute, this->lpItemAttributeNames[eAttribute], uiHeight, hlFalse);
						return hlTrue;
					}
					case HL_BSP_ITEM_PALETTE_ENTRIES:
					{
						hlUInt uiWidth = 0, uiHeight = 0, uiPaletteSize = 0;
						this->GetLumpInfo(*pFile, uiWidth, uiHeight, uiPaletteSize, hlFalse);
						hlAttributeSetUnsignedInteger(&Attribute, this->lpItemAttributeNames[eAttribute], uiPaletteSize, hlFalse);
						return hlTrue;
					}
				}
			}
			break;
		}
	}

	return hlFalse;
}

hlBool CBSPFile::GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
{
	if(pFile->GetID() < this->pTextureHeader->uiTextureCount)
	{
		hlUInt uiWidth, uiHeight, uiPaletteSize;
		if(!this->GetLumpInfo(*pFile, uiWidth, uiHeight, uiPaletteSize))
		{
			return hlFalse;
		}

		uiSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + uiPaletteSize * 4 + uiWidth * uiHeight;
	}
	else
	{
		uiSize = this->pHeader->lpLumps[HL_BSP_LUMP_ENTITIES].uiLength - 1;
	}

	return hlTrue;
}

hlBool CBSPFile::GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
{
	if(pFile->GetID() < this->pTextureHeader->uiTextureCount)
	{
		hlUInt uiWidth, uiHeight, uiPaletteSize;
		if(!this->GetLumpInfo(*pFile, uiWidth, uiHeight, uiPaletteSize))
		{
			return hlFalse;
		}

		hlUInt uiPixelSize = 0;
		for(hlUInt i = 0; i < HL_BSP_MIPMAP_COUNT; i++)
		{
			//if(pTexture->lpOffsets[i] != 0)
			{
				uiPixelSize += (uiWidth >> i) * (uiHeight >> i);
			}
		}

		uiSize = sizeof(BSPTexture) + uiPixelSize + sizeof(hlUInt16) + uiPaletteSize * 3;
	}
	else
	{
		uiSize = this->pHeader->lpLumps[HL_BSP_LUMP_ENTITIES].uiLength - 1;
	}

	return hlTrue;
}

hlBool CBSPFile::CreateStreamInternal(const CDirectoryFile *pFile, Streams::IStream *&pStream) const
{
	if(pFile->GetID() < this->pTextureHeader->uiTextureCount)
	{
		hlUInt uiWidth, uiHeight, uiPaletteSize;
		const hlByte *lpPalette, *lpPixels;

		if(!this->GetLumpInfo(*pFile, uiWidth, uiHeight, uiPaletteSize, lpPalette, lpPixels))
		{
			return hlFalse;
		}

		hlUInt uiBufferSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + uiPaletteSize * 4 + uiWidth * uiHeight;
		hlByte *lpBuffer = new hlByte[uiBufferSize];

		//
		// Allocate data.
		//

		BITMAPFILEHEADER *pFileHeader = (BITMAPFILEHEADER *)lpBuffer;
		BITMAPINFOHEADER *pInfoHeader = (BITMAPINFOHEADER *)((hlByte *)pFileHeader + sizeof(BITMAPFILEHEADER));
		hlByte *lpPaletteData = (hlByte *)pInfoHeader + sizeof(BITMAPINFOHEADER);
		hlByte *lpPixelData = lpPaletteData + uiPaletteSize * 4;

		memset(pFileHeader, 0, sizeof(BITMAPFILEHEADER));
		memset(pInfoHeader, 0, sizeof(BITMAPINFOHEADER));

		//
		// Fill in headers.
		//

		pFileHeader->bfType = ('M' << 8) | 'B';
		pFileHeader->bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + uiPaletteSize * 4 + uiWidth * uiHeight;
		pFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + uiPaletteSize * 4;

		pInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
		pInfoHeader->biWidth = uiWidth;
		pInfoHeader->biHeight = uiHeight;
		pInfoHeader->biPlanes = 1;
		pInfoHeader->biBitCount = 8;
		pInfoHeader->biSizeImage = 0;
		pInfoHeader->biClrUsed = uiPaletteSize;
		pInfoHeader->biClrImportant = uiPaletteSize;

		//
		// Fill in Palette data.
		//

		for(hlUInt i = 0; i < uiPaletteSize; i++)
		{
			lpPaletteData[i * 4 + 0] = lpPalette[i * 3 + 2];
			lpPaletteData[i * 4 + 1] = lpPalette[i * 3 + 1];
			lpPaletteData[i * 4 + 2] = lpPalette[i * 3 + 0];
			lpPaletteData[i * 4 + 3] = 0;
		}

		//
		// Fill in Index data.
		//

		for(hlUInt i = 0; i < uiWidth; i++)
		{
			for(hlUInt j = 0; j < uiHeight; j++)
			{
				lpPixelData[i + (uiHeight - 1 - j) * uiWidth] = lpPixels[i + j * uiWidth];
			}
		}

		pStream = new Streams::CMemoryStream(lpBuffer, uiBufferSize);
	}
	else
	{
		pStream = new Streams::CMappingStream(*this->pMapping, this->pHeader->lpLumps[HL_BSP_LUMP_ENTITIES].uiOffset, this->pHeader->lpLumps[HL_BSP_LUMP_ENTITIES].uiLength - 1);
	}

	return hlTrue;
}

hlVoid CBSPFile::ReleaseStreamInternal(Streams::IStream &Stream) const
{
	if(Stream.GetType() == HL_STREAM_MEMORY)
	{
		delete [](hlByte *)static_cast<Streams::CMemoryStream &>(Stream).GetBuffer();
	}
}

hlVoid CBSPFile::GetFileName(hlChar *lpBuffer, hlUInt uiBufferSize)
{
	if(lpBuffer == 0 || uiBufferSize == 0)
	{
		return;
	}

	const hlChar *lpMappingName = this->pMapping->GetFileName();

	if(lpMappingName == 0 && *lpMappingName == '\0')
	{
		*lpBuffer = '\0';
		return;
	}

	const hlChar *lpForward = strrchr(lpMappingName, '\\');
	const hlChar *lpBackward = strrchr(lpMappingName, '/');
	const hlChar *lpStart = lpForward > lpBackward ? lpForward : lpBackward;

	if(lpStart == 0)
	{
		lpStart = lpMappingName;
	}
	else
	{
		lpStart++;
	}

	const hlChar *lpEnd = strrchr(lpStart, '.');

	if(lpEnd == 0)
	{
		lpEnd = lpStart + strlen(lpStart);
	}

	if((hlUInt)(lpEnd - lpStart) + 1 < uiBufferSize)
	{
		uiBufferSize = (hlUInt)(lpEnd - lpStart) + 1;
	}

	strncpy(lpBuffer, lpStart, uiBufferSize);
	lpBuffer[uiBufferSize - 1] = '\0';
}

hlBool CBSPFile::GetLumpInfo(const CDirectoryFile &File, hlUInt &uiWidth, hlUInt &uiHeight, hlUInt &uiPaletteSize, hlUInt uiMipmap) const
{
	if(uiMipmap >= HL_BSP_MIPMAP_COUNT)
	{
		LastError.SetErrorMessageFormated("Error reading texture: invalid mipmap level %u.", uiMipmap);
		return hlFalse;
	}

	const BSPTexture *pTexture = (const BSPTexture *)((const hlByte *)this->pTextureHeader + this->pTextureHeader->lpOffsets[File.GetID()]);

	uiWidth = pTexture->uiWidth;
	uiHeight = pTexture->uiHeight;

	hlUInt uiPixelSize = 0;
	for(hlUInt i = 0; i < HL_BSP_MIPMAP_COUNT; i++)
	{
		if(pTexture->lpOffsets[i] != 0)
		{
			uiPixelSize += (uiWidth >> i) * (uiHeight >> i);
		}
	}

	const hlByte *lpData = (const hlByte *)pTexture + pTexture->lpOffsets[0];

	uiPaletteSize = (hlUInt)*(const hlUInt16 *)(lpData + uiPixelSize);

	switch(uiMipmap)
	{
	case 1:
		uiWidth /= 2;
		uiHeight /= 2;
		break;
	case 2:
		uiWidth /= 4;
		uiHeight /= 4;
		break;
	case 3:
		uiWidth /= 8;
		uiHeight /= 8;
		break;
	}

	return hlTrue;
}

hlBool CBSPFile::GetLumpInfo(const CDirectoryFile &File, hlUInt &uiWidth, hlUInt &uiHeight, hlUInt &uiPaletteSize, const hlByte *&lpPalette, const hlByte *&lpPixels, hlUInt uiMipmap) const
{
	if(uiMipmap > 3)
	{
		LastError.SetErrorMessageFormated("Error reading texture: invalid mipmap level %u.", uiMipmap);
		return hlFalse;
	}

	const BSPTexture *pTexture = (const BSPTexture *)((const hlByte *)this->pTextureHeader + this->pTextureHeader->lpOffsets[File.GetID()]);

	uiWidth = pTexture->uiWidth;
	uiHeight = pTexture->uiHeight;

	hlUInt uiPixelSize = 0;
	for(hlUInt i = 0; i < HL_BSP_MIPMAP_COUNT; i++)
	{
		if(pTexture->lpOffsets[i] != 0)
		{
			uiPixelSize += (uiWidth >> i) * (uiHeight >> i);
		}
	}

	lpPixels = (const hlByte *)pTexture + pTexture->lpOffsets[uiMipmap];

	uiPaletteSize = (hlUInt)*(const hlUInt16 *)(((const hlByte *)pTexture + pTexture->lpOffsets[0]) + uiPixelSize);

	lpPalette = ((const hlByte *)pTexture + pTexture->lpOffsets[0]) + uiPixelSize + sizeof(hlUInt16);

	switch(uiMipmap)
	{
	case 1:
		uiWidth /= 2;
		uiHeight /= 2;
		break;
	case 2:
		uiWidth /= 4;
		uiHeight /= 4;
		break;
	case 3:
		uiWidth /= 8;
		uiHeight /= 8;
		break;
	}

	return hlTrue;
}
<commit_msg>Delete BSPFile.cpp<commit_after><|endoftext|>


<commit_before>/*
 * @file laplace.hpp
 * @author Zhihao Lou
 *
 * Laplace (double exponential) distribution used in SA.
 */

#ifndef __MLPACK_CORE_OPTIMIZER_SA_LAPLACE_DISTRIBUTION_HPP
#define __MLPACK_CORE_OPTIMIZER_SA_LAPLACE_DISTRIBUTION_HPP

namespace mlpack {
namespace distribution {

/**
 * The multivariate Laplace distribution centered at 0 has pdf
 *
 * \f[
 * f(x|\theta) = \frac{1}{2 \theta}\exp\left(-\frac{\|x - \mu\|}{\theta}\right)
 * \f]
 *
 * given scale parameter \f$\theta\f$ and mean \f$\mu\f$.  This implementation
 * assumes a diagonal covariance, but a rewrite to support arbitrary covariances
 * is possible.
 *
 * See the following paper for more information on the non-diagonal-covariance
 * Laplace distribution and estimation techniques:
 *
 * @code
 * @article{eltoft2006multivariate,
 *   title={{On the Multivariate Laplace Distribution}},
 *   author={Eltoft, Torbj\orn and Kim, Taesu and Lee, Te-Won},
 *   journal={IEEE Signal Processing Letters},
 *   volume={13},
 *   number={5},
 *   pages={300--304},
 *   year={2006}
 * }
 * @endcode
 *
 * Note that because of the diagonal covariance restriction, much of the algebra
 * in the paper above becomes simplified, and the PDF takes roughly the same
 * form as the univariate case.
 */
class LaplaceDistribution
{
 public:
  /**
   * Default constructor, which creates a Laplace distribution with zero
   * dimension and zero scale parameter.
   */
  LaplaceDistribution() : scale(0) { }

  /**
   * Construct the Laplace distribution with the given scale and dimensionality.
   * The mean is initialized to zero.
   *
   * @param dimensionality Dimensionality of distribution.
   * @param scale Scale of distribution.
   */
  LaplaceDistribution(const size_t dimensionality, const double scale) :
      mean(arma::zeros<arma::vec>(dimensionality)), scale(scale) { }

  /**
   * Construct the Laplace distribution with the given mean and scale parameter.
   *
   * @param mean Mean of distribution.
   * @param scale Scale of distribution.
   */
  LaplaceDistribution(const arma::vec& mean, const double scale) :
      mean(mean), scale(scale) { }

  //! Return the dimensionality of this distribution.
  size_t Dimensionality() const { return mean.n_elem; }

  /**
   * Return the probability of the given observation.
   */
  double Probability(const arma::vec& observation) const;

  /**
   * Return a randomly generated observation according to the probability
   * distribution defined by this object.  This is inlined for speed.
   *
   * @return Random observation from this Laplace distribution.
   */
  arma::vec Random() const
  {
    arma::vec result(mean.n_elem);
    result.randu();

    // Convert from uniform distribution to Laplace distribution.
    return mean - scale * sign(result) % arma::log(1 - 2.0 * (result - 0.5));
  }

  /**
   * Estimate the Laplace distribution directly from the given observations.
   *
   * @param observations List of observations.
   */
  void Estimate(const arma::mat& observations);

  /**
   * Estimate the Laplace distribution from the given observations, taking into
   * account the probability of each observation actually being from this
   * distribution.
   */
  void Estimate(const arma::mat& observations,
                const arma::vec& probabilities);

  //! Return the mean.
  const arma::vec& Mean() const { return mean; }
  //! Modify the mean.
  arma::vec& Mean() { return mean; }

  //! Return the scale parameter.
  double Scale() const { return scale; }
  //! Modify the scale parameter.
  double& Scale() { return scale; }

  //! Return a string representation of the object.
  std::string ToString() const;

 private:
  //! Mean of the distribution.
  arma::vec mean;
  //! Scale parameter of the distribution.
  double scale;

};

}; // namespace distribution
}; // namespace mlpack

#endif
<commit_msg>Explicitly use arma::sign().<commit_after>/*
 * @file laplace.hpp
 * @author Zhihao Lou
 *
 * Laplace (double exponential) distribution used in SA.
 */

#ifndef __MLPACK_CORE_OPTIMIZER_SA_LAPLACE_DISTRIBUTION_HPP
#define __MLPACK_CORE_OPTIMIZER_SA_LAPLACE_DISTRIBUTION_HPP

namespace mlpack {
namespace distribution {

/**
 * The multivariate Laplace distribution centered at 0 has pdf
 *
 * \f[
 * f(x|\theta) = \frac{1}{2 \theta}\exp\left(-\frac{\|x - \mu\|}{\theta}\right)
 * \f]
 *
 * given scale parameter \f$\theta\f$ and mean \f$\mu\f$.  This implementation
 * assumes a diagonal covariance, but a rewrite to support arbitrary covariances
 * is possible.
 *
 * See the following paper for more information on the non-diagonal-covariance
 * Laplace distribution and estimation techniques:
 *
 * @code
 * @article{eltoft2006multivariate,
 *   title={{On the Multivariate Laplace Distribution}},
 *   author={Eltoft, Torbj\orn and Kim, Taesu and Lee, Te-Won},
 *   journal={IEEE Signal Processing Letters},
 *   volume={13},
 *   number={5},
 *   pages={300--304},
 *   year={2006}
 * }
 * @endcode
 *
 * Note that because of the diagonal covariance restriction, much of the algebra
 * in the paper above becomes simplified, and the PDF takes roughly the same
 * form as the univariate case.
 */
class LaplaceDistribution
{
 public:
  /**
   * Default constructor, which creates a Laplace distribution with zero
   * dimension and zero scale parameter.
   */
  LaplaceDistribution() : scale(0) { }

  /**
   * Construct the Laplace distribution with the given scale and dimensionality.
   * The mean is initialized to zero.
   *
   * @param dimensionality Dimensionality of distribution.
   * @param scale Scale of distribution.
   */
  LaplaceDistribution(const size_t dimensionality, const double scale) :
      mean(arma::zeros<arma::vec>(dimensionality)), scale(scale) { }

  /**
   * Construct the Laplace distribution with the given mean and scale parameter.
   *
   * @param mean Mean of distribution.
   * @param scale Scale of distribution.
   */
  LaplaceDistribution(const arma::vec& mean, const double scale) :
      mean(mean), scale(scale) { }

  //! Return the dimensionality of this distribution.
  size_t Dimensionality() const { return mean.n_elem; }

  /**
   * Return the probability of the given observation.
   */
  double Probability(const arma::vec& observation) const;

  /**
   * Return a randomly generated observation according to the probability
   * distribution defined by this object.  This is inlined for speed.
   *
   * @return Random observation from this Laplace distribution.
   */
  arma::vec Random() const
  {
    arma::vec result(mean.n_elem);
    result.randu();

    // Convert from uniform distribution to Laplace distribution.
    return mean - scale * arma::sign(result) % arma::log(1 - 2.0 * (result -
        0.5));
  }

  /**
   * Estimate the Laplace distribution directly from the given observations.
   *
   * @param observations List of observations.
   */
  void Estimate(const arma::mat& observations);

  /**
   * Estimate the Laplace distribution from the given observations, taking into
   * account the probability of each observation actually being from this
   * distribution.
   */
  void Estimate(const arma::mat& observations,
                const arma::vec& probabilities);

  //! Return the mean.
  const arma::vec& Mean() const { return mean; }
  //! Modify the mean.
  arma::vec& Mean() { return mean; }

  //! Return the scale parameter.
  double Scale() const { return scale; }
  //! Modify the scale parameter.
  double& Scale() { return scale; }

  //! Return a string representation of the object.
  std::string ToString() const;

 private:
  //! Mean of the distribution.
  arma::vec mean;
  //! Scale parameter of the distribution.
  double scale;

};

}; // namespace distribution
}; // namespace mlpack

#endif
<|endoftext|>


<commit_before>/**
 * @file sparse_autoencoder_test.cpp
 * @author Siddharth Agrawal
 *
 * Test the SparseAutoencoder class.
 */
#include <mlpack/methods/sparse_autoencoder/sparse_autoencoder_function.hpp>
#include <mlpack/methods/sparse_autoencoder/activation_functions/logistic_function.hpp>

#include <mlpack/core.hpp>
#include <mlpack/methods/sparse_autoencoder/layer/base_layer.hpp>

#include <boost/test/unit_test.hpp>
#include "old_boost_test_definitions.hpp"

using namespace mlpack;
using namespace arma;

using SigmoidLayer = nn::SigmoidLayer<nn::LogisticFunction>;

//sparse autoencoder function
using SAEF = nn::SparseAutoencoderFunction<SigmoidLayer, SigmoidLayer>;
//sparse autoencoder function greedy
using SAEFG = nn::SparseAutoencoderFunction<SigmoidLayer, SigmoidLayer, std::true_type>;

BOOST_AUTO_TEST_SUITE(SparseAutoencoderTest2);

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionEvaluate)
{
  const size_t vSize = 5;
  const size_t hSize = 3;
  const size_t r = 2 * hSize + 1;
  const size_t c = vSize + 1;

  // Simple fake dataset.
  arma::mat data1("0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5");
  // Transpose of the above dataset.
  arma::mat data2 = data1.t();

  // Create a SparseAutoencoderFunction. Regularization and KL divergence terms
  // ignored.
  SAEF saf1(data1, vSize, hSize, 0, 0);

  // Test using first dataset. Values were calculated using Octave.
  BOOST_REQUIRE_CLOSE(saf1.Evaluate(arma::ones(r, c)), 1.190472606540, 1e-5);
  BOOST_REQUIRE_CLOSE(saf1.Evaluate(arma::zeros(r, c)), 0.150000000000, 1e-5);
  BOOST_REQUIRE_CLOSE(saf1.Evaluate(-arma::ones(r, c)), 0.048800332266, 1e-5);

  // Create a SparseAutoencoderFunction. Regularization and KL divergence terms
  // ignored.
  SAEF saf2(data2, vSize, hSize, 0, 0);

  // Test using second dataset. Values were calculated using Octave.
  BOOST_REQUIRE_CLOSE(saf2.Evaluate(arma::ones(r, c)), 1.197585812647, 1e-5);
  BOOST_REQUIRE_CLOSE(saf2.Evaluate(arma::zeros(r, c)), 0.150000000000, 1e-5);
  BOOST_REQUIRE_CLOSE(saf2.Evaluate(-arma::ones(r, c)), 0.063466617408, 1e-5);
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionRandomEvaluate)
{
  const size_t points = 1000;
  const size_t trials = 50;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l1 = hSize;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // Create a SparseAutoencoderFunction. Regularization and KL divergence terms
  // ignored.
  SAEF saf(data, vSize, hSize, 0, 0);

  // Run a number of trials.
  for (size_t i = 0; i < trials; i++)
  {
    // Create a random set of parameters.
    arma::mat parameters;
    parameters.randu(l3 + 1, l2 + 1);

    double reconstructionError = 0;

    // Compute error for each training example.
    for (size_t j = 0; j < points; j++)
    {
      arma::mat hiddenLayer, outputLayer, diff;

      hiddenLayer = 1.0 /
                   (1 + arma::exp(-(parameters.submat(0, 0, l1 - 1, l2 - 1) *
                                  data.col(j) + parameters.submat(0, l2, l1 - 1, l2))));
      outputLayer = 1.0 /
                    (1 + arma::exp(-(parameters.submat(l1, 0, l3 - 1,l2 - 1).t()
                                   * hiddenLayer + parameters.submat(l3, 0, l3, l2 - 1).t())));
      diff = outputLayer - data.col(j);

      reconstructionError += 0.5 * arma::sum(arma::sum(diff % diff));
    }
    reconstructionError /= points;

    // Compare with the value returned by the function.
    BOOST_REQUIRE_CLOSE(saf.Evaluate(parameters), reconstructionError, 1e-5);
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionRegularizationEvaluate)
{
  const size_t points = 1000;
  const size_t trials = 50;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // 3 objects for comparing regularization costs.
  SAEF safNoReg(data, vSize, hSize, 0, 0);
  SAEF safSmallReg(data, vSize, hSize, 0.5, 0);
  SAEF safBigReg(data, vSize, hSize, 20, 0);

  // Run a number of trials.
  for (size_t i = 0; i < trials; i++)
  {
    // Create a random set of parameters.
    arma::mat parameters;
    parameters.randu(l3 + 1, l2 + 1);

    double wL2SquaredNorm;

    wL2SquaredNorm = arma::accu(parameters.submat(0, 0, l3 - 1, l2 - 1) %
                                parameters.submat(0, 0, l3 - 1, l2 - 1));

    // Calculate regularization terms.
    const double smallRegTerm = 0.25 * wL2SquaredNorm;
    const double bigRegTerm = 10 * wL2SquaredNorm;

    BOOST_REQUIRE_CLOSE(safNoReg.Evaluate(parameters) + smallRegTerm,
                        safSmallReg.Evaluate(parameters), 1e-5);
    BOOST_REQUIRE_CLOSE(safNoReg.Evaluate(parameters) + bigRegTerm,
                        safBigReg.Evaluate(parameters), 1e-5);
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionKLDivergenceEvaluate)
{
  const size_t points = 1000;
  const size_t trials = 50;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l1 = hSize;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  const double rho = 0.01;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // 3 objects for comparing divergence costs.
  SAEF safNoDiv(data, vSize, hSize, 0, 0, rho);
  SAEF safSmallDiv(data, vSize, hSize, 0, 5, rho);
  SAEF safBigDiv(data, vSize, hSize, 0, 20, rho);

  // Run a number of trials.
  for(size_t i = 0; i < trials; i++)
  {
    // Create a random set of parameters.
    arma::mat parameters;
    parameters.randu(l3 + 1, l2 + 1);

    arma::mat rhoCap;
    rhoCap.zeros(hSize, 1);

    // Compute hidden layer activations for each example.
    for (size_t j = 0; j < points; j++)
    {
      arma::mat hiddenLayer;

      hiddenLayer = 1.0 / (1 +
                           arma::exp(-(parameters.submat(0, 0, l1 - 1, l2 - 1) *
                                       data.col(j) + parameters.submat(0, l2, l1 - 1, l2))));
      rhoCap += hiddenLayer;
    }
    rhoCap /= points;

    // Calculate divergence terms.
    const double smallDivTerm = 5 * arma::accu(rho * arma::log(rho / rhoCap) +
                                               (1 - rho) * arma::log((1 - rho) / (1 - rhoCap)));
    const double bigDivTerm = 20 * arma::accu(rho * arma::log(rho / rhoCap) +
                                              (1 - rho) * arma::log((1 - rho) / (1 - rhoCap)));

    BOOST_REQUIRE_CLOSE(safNoDiv.Evaluate(parameters) + smallDivTerm,
                        safSmallDiv.Evaluate(parameters), 1e-5);
    BOOST_REQUIRE_CLOSE(safNoDiv.Evaluate(parameters) + bigDivTerm,
                        safBigDiv.Evaluate(parameters), 1e-5);
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionGradient)
{
  const size_t points = 1000;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // 3 objects for 3 terms in the cost function. Each term contributes towards
  // the gradient and thus need to be checked independently.
  SAEFG saf1(data, vSize, hSize, 0, 0);
  SAEFG saf2(data, vSize, hSize, 20, 0);
  SAEFG saf3(data, vSize, hSize, 20, 20);

  // Create a random set of parameters.
  arma::mat parameters;
  parameters.randu(l3 + 1, l2 + 1);

  // Get gradients for the current parameters.
  arma::mat gradient1, gradient2, gradient3;
  saf1.Gradient(parameters, gradient1);
  saf2.Gradient(parameters, gradient2);
  saf3.Gradient(parameters, gradient3);

  // Perturbation constant.
  const double epsilon = 0.0001;
  double costPlus1, costMinus1, numGradient1;
  double costPlus2, costMinus2, numGradient2;
  double costPlus3, costMinus3, numGradient3;

  // For each parameter.
  for (size_t i = 0; i <= l3; i++)
  {
    for (size_t j = 0; j <= l2; j++)
    {
      // Perturb parameter with a positive constant and get costs.
      parameters(i, j) += epsilon;
      costPlus1 = saf1.Evaluate(parameters);
      costPlus2 = saf2.Evaluate(parameters);
      costPlus3 = saf3.Evaluate(parameters);

      // Perturb parameter with a negative constant and get costs.
      parameters(i, j) -= 2 * epsilon;
      costMinus1 = saf1.Evaluate(parameters);
      costMinus2 = saf2.Evaluate(parameters);
      costMinus3 = saf3.Evaluate(parameters);

      // Compute numerical gradients using the costs calculated above.
      numGradient1 = (costPlus1 - costMinus1) / (2 * epsilon);
      numGradient2 = (costPlus2 - costMinus2) / (2 * epsilon);
      numGradient3 = (costPlus3 - costMinus3) / (2 * epsilon);

      // Restore the parameter value.
      parameters(i, j) += epsilon;

      // Compare numerical and backpropagation gradient values.
      BOOST_REQUIRE_CLOSE(numGradient1, gradient1(i, j), 1e-2);
      BOOST_REQUIRE_CLOSE(numGradient2, gradient2(i, j), 1e-2);
      BOOST_REQUIRE_CLOSE(numGradient3, gradient3(i, j), 1e-2);
    }
  }
}

BOOST_AUTO_TEST_SUITE_END();
<commit_msg>add test case for move<commit_after>/**
 * @file sparse_autoencoder_test.cpp
 * @author Siddharth Agrawal
 *
 * Test the SparseAutoencoder class.
 */
#include <mlpack/methods/sparse_autoencoder/sparse_autoencoder.hpp>
#include <mlpack/methods/sparse_autoencoder/sparse_autoencoder_function.hpp>
#include <mlpack/methods/sparse_autoencoder/activation_functions/logistic_function.hpp>

#include <mlpack/core.hpp>
#include <mlpack/methods/sparse_autoencoder/layer/base_layer.hpp>

#include <boost/test/unit_test.hpp>
#include "old_boost_test_definitions.hpp"

using namespace mlpack;
using namespace arma;

using SigmoidLayer = nn::SigmoidLayer<nn::LogisticFunction>;

//sparse autoencoder function
using SAEF = nn::SparseAutoencoderFunction<SigmoidLayer, SigmoidLayer>;
//sparse autoencoder function greedy
using SAEFG = nn::SparseAutoencoderFunction<SigmoidLayer, SigmoidLayer, std::true_type>;

BOOST_AUTO_TEST_SUITE(SparseAutoencoderTest2);

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionEvaluate)
{
  const size_t vSize = 5;
  const size_t hSize = 3;
  const size_t r = 2 * hSize + 1;
  const size_t c = vSize + 1;

  // Simple fake dataset.
  arma::mat data1("0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5;"
                  "0.1 0.2 0.3 0.4 0.5");
  // Transpose of the above dataset.
  arma::mat data2 = data1.t();

  // Create a SparseAutoencoderFunction. Regularization and KL divergence terms
  // ignored.
  SAEF saf1(data1, vSize, hSize, 0, 0);

  // Test using first dataset. Values were calculated using Octave.
  BOOST_REQUIRE_CLOSE(saf1.Evaluate(arma::ones(r, c)), 1.190472606540, 1e-5);
  BOOST_REQUIRE_CLOSE(saf1.Evaluate(arma::zeros(r, c)), 0.150000000000, 1e-5);
  BOOST_REQUIRE_CLOSE(saf1.Evaluate(-arma::ones(r, c)), 0.048800332266, 1e-5);

  // Create a SparseAutoencoderFunction. Regularization and KL divergence terms
  // ignored.
  SAEF saf2(data2, vSize, hSize, 0, 0);

  // Test using second dataset. Values were calculated using Octave.
  BOOST_REQUIRE_CLOSE(saf2.Evaluate(arma::ones(r, c)), 1.197585812647, 1e-5);
  BOOST_REQUIRE_CLOSE(saf2.Evaluate(arma::zeros(r, c)), 0.150000000000, 1e-5);
  BOOST_REQUIRE_CLOSE(saf2.Evaluate(-arma::ones(r, c)), 0.063466617408, 1e-5);
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionRandomEvaluate)
{
  const size_t points = 1000;
  const size_t trials = 50;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l1 = hSize;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // Create a SparseAutoencoderFunction. Regularization and KL divergence terms
  // ignored.
  SAEF saf(data, vSize, hSize, 0, 0);

  // Run a number of trials.
  for (size_t i = 0; i < trials; i++)
  {
    // Create a random set of parameters.
    arma::mat parameters;
    parameters.randu(l3 + 1, l2 + 1);

    double reconstructionError = 0;

    // Compute error for each training example.
    for (size_t j = 0; j < points; j++)
    {
      arma::mat hiddenLayer, outputLayer, diff;

      hiddenLayer = 1.0 /
                   (1 + arma::exp(-(parameters.submat(0, 0, l1 - 1, l2 - 1) *
                                  data.col(j) + parameters.submat(0, l2, l1 - 1, l2))));
      outputLayer = 1.0 /
                    (1 + arma::exp(-(parameters.submat(l1, 0, l3 - 1,l2 - 1).t()
                                   * hiddenLayer + parameters.submat(l3, 0, l3, l2 - 1).t())));
      diff = outputLayer - data.col(j);

      reconstructionError += 0.5 * arma::sum(arma::sum(diff % diff));
    }
    reconstructionError /= points;

    // Compare with the value returned by the function.
    BOOST_REQUIRE_CLOSE(saf.Evaluate(parameters), reconstructionError, 1e-5);
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionRegularizationEvaluate)
{
  const size_t points = 1000;
  const size_t trials = 50;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // 3 objects for comparing regularization costs.
  SAEF safNoReg(data, vSize, hSize, 0, 0);
  SAEF safSmallReg(data, vSize, hSize, 0.5, 0);
  SAEF safBigReg(data, vSize, hSize, 20, 0);

  // Run a number of trials.
  for (size_t i = 0; i < trials; i++)
  {
    // Create a random set of parameters.
    arma::mat parameters;
    parameters.randu(l3 + 1, l2 + 1);

    double wL2SquaredNorm;

    wL2SquaredNorm = arma::accu(parameters.submat(0, 0, l3 - 1, l2 - 1) %
                                parameters.submat(0, 0, l3 - 1, l2 - 1));

    // Calculate regularization terms.
    const double smallRegTerm = 0.25 * wL2SquaredNorm;
    const double bigRegTerm = 10 * wL2SquaredNorm;

    BOOST_REQUIRE_CLOSE(safNoReg.Evaluate(parameters) + smallRegTerm,
                        safSmallReg.Evaluate(parameters), 1e-5);
    BOOST_REQUIRE_CLOSE(safNoReg.Evaluate(parameters) + bigRegTerm,
                        safBigReg.Evaluate(parameters), 1e-5);
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionKLDivergenceEvaluate)
{
  const size_t points = 1000;
  const size_t trials = 50;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l1 = hSize;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  const double rho = 0.01;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // 3 objects for comparing divergence costs.
  SAEF safNoDiv(data, vSize, hSize, 0, 0, rho);
  SAEF safSmallDiv(data, vSize, hSize, 0, 5, rho);
  SAEF safBigDiv(data, vSize, hSize, 0, 20, rho);

  // Run a number of trials.
  for(size_t i = 0; i < trials; i++)
  {
    // Create a random set of parameters.
    arma::mat parameters;
    parameters.randu(l3 + 1, l2 + 1);

    arma::mat rhoCap;
    rhoCap.zeros(hSize, 1);

    // Compute hidden layer activations for each example.
    for (size_t j = 0; j < points; j++)
    {
      arma::mat hiddenLayer;

      hiddenLayer = 1.0 / (1 +
                           arma::exp(-(parameters.submat(0, 0, l1 - 1, l2 - 1) *
                                       data.col(j) + parameters.submat(0, l2, l1 - 1, l2))));
      rhoCap += hiddenLayer;
    }
    rhoCap /= points;

    // Calculate divergence terms.
    const double smallDivTerm = 5 * arma::accu(rho * arma::log(rho / rhoCap) +
                                               (1 - rho) * arma::log((1 - rho) / (1 - rhoCap)));
    const double bigDivTerm = 20 * arma::accu(rho * arma::log(rho / rhoCap) +
                                              (1 - rho) * arma::log((1 - rho) / (1 - rhoCap)));

    BOOST_REQUIRE_CLOSE(safNoDiv.Evaluate(parameters) + smallDivTerm,
                        safSmallDiv.Evaluate(parameters), 1e-5);
    BOOST_REQUIRE_CLOSE(safNoDiv.Evaluate(parameters) + bigDivTerm,
                        safBigDiv.Evaluate(parameters), 1e-5);
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderFunctionGradient)
{
  const size_t points = 1000;
  const size_t vSize = 20;
  const size_t hSize = 10;
  const size_t l2 = vSize;
  const size_t l3 = 2 * hSize;

  // Initialize a random dataset.
  arma::mat data;
  data.randu(vSize, points);

  // 3 objects for 3 terms in the cost function. Each term contributes towards
  // the gradient and thus need to be checked independently.
  SAEFG saf1(data, vSize, hSize, 0, 0);
  SAEFG saf2(data, vSize, hSize, 20, 0);
  SAEFG saf3(data, vSize, hSize, 20, 20);

  // Create a random set of parameters.
  arma::mat parameters;
  parameters.randu(l3 + 1, l2 + 1);

  // Get gradients for the current parameters.
  arma::mat gradient1, gradient2, gradient3;
  saf1.Gradient(parameters, gradient1);
  saf2.Gradient(parameters, gradient2);
  saf3.Gradient(parameters, gradient3);

  // Perturbation constant.
  const double epsilon = 0.0001;
  double costPlus1, costMinus1, numGradient1;
  double costPlus2, costMinus2, numGradient2;
  double costPlus3, costMinus3, numGradient3;

  // For each parameter.
  for (size_t i = 0; i <= l3; i++)
  {
    for (size_t j = 0; j <= l2; j++)
    {
      // Perturb parameter with a positive constant and get costs.
      parameters(i, j) += epsilon;
      costPlus1 = saf1.Evaluate(parameters);
      costPlus2 = saf2.Evaluate(parameters);
      costPlus3 = saf3.Evaluate(parameters);

      // Perturb parameter with a negative constant and get costs.
      parameters(i, j) -= 2 * epsilon;
      costMinus1 = saf1.Evaluate(parameters);
      costMinus2 = saf2.Evaluate(parameters);
      costMinus3 = saf3.Evaluate(parameters);

      // Compute numerical gradients using the costs calculated above.
      numGradient1 = (costPlus1 - costMinus1) / (2 * epsilon);
      numGradient2 = (costPlus2 - costMinus2) / (2 * epsilon);
      numGradient3 = (costPlus3 - costMinus3) / (2 * epsilon);

      // Restore the parameter value.
      parameters(i, j) += epsilon;

      // Compare numerical and backpropagation gradient values.
      BOOST_REQUIRE_CLOSE(numGradient1, gradient1(i, j), 1e-2);
      BOOST_REQUIRE_CLOSE(numGradient2, gradient2(i, j), 1e-2);
      BOOST_REQUIRE_CLOSE(numGradient3, gradient3(i, j), 1e-2);
    }
  }
}

BOOST_AUTO_TEST_CASE(SparseAutoencoderMoveTest)
{
  using SAE = mlpack::nn::SparseAutoencoder<>;
  SAE sae1(2, 2);
  SAE sae2(std::move(sae1));
  BOOST_REQUIRE(sae1.Parameters().n_elem == 0);
  BOOST_REQUIRE(sae1.VisibleSize(), sae2.VisibleSize());
  BOOST_REQUIRE(sae1.HiddenSize(), sae2.HiddenSize());
  BOOST_REQUIRE_CLOSE(sae1.Lambda(), sae2.Lambda(), 1e-5);
  BOOST_REQUIRE_CLOSE(sae1.Beta(), sae2.Beta(), 1e-5);
  BOOST_REQUIRE_CLOSE(sae1.Rho(), sae2.Rho(), 1e-5);
}

BOOST_AUTO_TEST_SUITE_END();
<|endoftext|>


<commit_before>// Copyright 2015 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "elang/optimizer/scheduler/visual_schedule.h"

#include "base/strings/stringprintf.h"
#include "elang/optimizer/function.h"
#include "elang/optimizer/nodes.h"
#include "elang/optimizer/opcode.h"
#include "elang/optimizer/scheduler/basic_block.h"
#include "elang/optimizer/scheduler/control_flow_graph.h"
#include "elang/optimizer/scheduler/schedule.h"

namespace elang {
namespace optimizer {

namespace {
base::StringPiece PrefixOf(Node* node) {
  if (node->IsControl())
    return "%c";
  if (node->IsEffect())
    return "%e";
  if (node->IsTuple())
    return "%t";
  return "%r";
}
}  // namespace

std::ostream& operator<<(std::ostream& ostream, const VisualSchedule& wrapper) {
  ostream << "digraph IR {" << std::endl
          << "  concentrate=false" << std::endl
          << "  node [fontname=monospace fontsize=10]" << std::endl
          << "  overlap=false" << std::endl
          << "  rankdir=\"TB\"" << std::endl
          << "  ranksep=\"0.2 equally\"" << std::endl
          << "  splines=true" << std::endl
          << std::endl;

  auto& schedule = *wrapper.schedule;
  auto last = static_cast<const Node*>(nullptr);
  for (auto const node : schedule.nodes()) {
    if (node->IsBlockStart()) {
      ostream << "  subgraph cluster_" << node->id() << " {" << std::endl;
      last = nullptr;
    }
    ostream << "    node" << node->id() << " [shape=record "
            << "label=\"{{" << PrefixOf(node) << node->id() << "="
            << node->mnemonic();
    for (auto const input : node->inputs())
      ostream << "|" << PrefixOf(input) << input->id();
    ostream << "}}\"]" << std::endl;
    if (last) {
      ostream << "    node" << last->id() << " -> node" << node->id()
              << std::endl;
    }
    last = node;
    if (node->IsBlockEnd())
      ostream << "  }" << std::endl;
  }

  ostream << std::endl
          << "  // Edges" << std::endl;
  for (auto const node : schedule.nodes()) {
    if (!node->IsBlockStart())
      continue;
    auto position = 0;
    auto const to = node->id();
    for (auto const input : node->inputs()) {
      auto const from = input->id();
      ostream << "  node" << from << " -> node" << to;
      if (position && node->opcode() == Opcode::Loop)
        ostream << " [color=red constraint=false]";
      ostream << std::endl;
      ++position;
    }
  }
  return ostream << "}" << std::endl;
}

VisualSchedule AsVisual(const Schedule& schedule) {
  return VisualSchedule{&schedule};
}

}  // namespace optimizer
}  // namespace elang
<commit_msg>elang/optimizer/scheduler: Utilize "\l" syntax of Graphviz label value for |VisualScheudle|.<commit_after>// Copyright 2015 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <unordered_map>

#include "elang/optimizer/scheduler/visual_schedule.h"

#include "base/strings/stringprintf.h"
#include "elang/optimizer/function.h"
#include "elang/optimizer/nodes.h"
#include "elang/optimizer/opcode.h"
#include "elang/optimizer/scheduler/basic_block.h"
#include "elang/optimizer/scheduler/control_flow_graph.h"
#include "elang/optimizer/scheduler/schedule.h"

namespace elang {
namespace optimizer {

namespace {
base::StringPiece PrefixOf(Node* node) {
  if (node->IsControl())
    return "%c";
  if (node->IsEffect())
    return "%e";
  if (node->IsTuple())
    return "%t";
  return "%r";
}
}  // namespace

std::ostream& operator<<(std::ostream& ostream, const VisualSchedule& wrapper) {
  ostream << "digraph IR {" << std::endl
          << "  concentrate=false" << std::endl
          << "  node [fontname=monospace fontsize=10]" << std::endl
          << "  overlap=false" << std::endl
          << "  rankdir=\"TB\"" << std::endl
          << "  ranksep=\"0.8 equally\"" << std::endl
          << "  splines=true" << std::endl
          << "  node [shape=box]" << std::endl
          << std::endl;
  std::unordered_map<Node*, Node*> end_to_start_map;
  Node* start_node = nullptr;
  auto& schedule = *wrapper.schedule;
  for (auto const node : schedule.nodes()) {
    if (node->IsBlockStart()) {
      ostream << " node" << node->id() << " [label=\"";
      start_node = node;
    } else {
      DCHECK(start_node);
    }
    ostream << PrefixOf(node) << node->id() << "=" << node->mnemonic();
    for (auto const input : node->inputs())
      ostream << " " << PrefixOf(input) << input->id();
    ostream << "\\l";
    if (!node->IsBlockEnd())
      continue;
    ostream << "\"]" << std::endl;
    end_to_start_map.insert(std::make_pair(node, start_node));
    start_node = nullptr;
  }

  ostream << std::endl << "  // Edges" << std::endl;
  for (auto const node : schedule.nodes()) {
    if (!node->IsBlockStart())
      continue;
    auto position = 0;
    auto const to = node;
    for (auto const input : node->inputs()) {
      auto const it = end_to_start_map.find(input);
      DCHECK(it != end_to_start_map.end());
      auto const from = it->second;
      auto const is_back_edge = position && node->opcode() == Opcode::Loop;
      auto const port = is_back_edge ? ":w" : "";
      ostream << "  node" << from->id() << port << " -> node" << to->id()
              << port;
      if (is_back_edge)
        ostream << " [color=red constraint=false]";
      ostream << std::endl;
      ++position;
    }
  }
  return ostream << "}" << std::endl;
}

VisualSchedule AsVisual(const Schedule& schedule) {
  return VisualSchedule{&schedule};
}

}  // namespace optimizer
}  // namespace elang
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 Google LLC
 * Copyright (c) 2019 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*--------------------------------------------------------------------*/

#include "vktAmberTestCase.hpp"
#include "vktTestGroupUtil.hpp"

namespace vkt
{
namespace cts_amber
{

class AmberIndexFileParser
{
	char*				m_buf;
	size_t				m_idx;
	size_t				m_len;
	static const int	m_fieldLen = 256;
	char				m_scratch[m_fieldLen];
	char				m_filenameField[m_fieldLen];
	char				m_testnameField[m_fieldLen];
	char				m_descField[m_fieldLen];

	bool isWhitespace (char c)
	{
		if (c == ' '  ||
			c == '\t' ||
			c == '\r' ||
			c == '\n')
		{
			return true;
		}
		return false;
	}

	void skipWhitespace (void)
	{
		while (m_idx < m_len && isWhitespace(m_buf[m_idx]))
			m_idx++;
	}

	void accept (char c)
	{
		if (m_buf[m_idx] == c)
			m_idx++;
	}

	void expect (char c)
	{
		if (m_buf[m_idx] != c || m_idx >= m_len)
			TCU_THROW(ResourceError, "Error parsing amber index file");

		m_idx++;
	}

	void captureString (char* field)
	{
		int i = 0;

		while (m_idx < m_len && i < m_fieldLen && m_buf[m_idx] != '"')
		{
			field[i] = m_buf[m_idx];
			i++;
			m_idx++;
		}

		field[i] = 0;
		m_idx++;
	}

	char* loadFile (const char* filename, size_t& len)
	{
		FILE* f = fopen(filename, "rb");

		if (f == 0)
		{
			std::string error("Unable to open index file ");
			error.append(filename);
			TCU_THROW(ResourceError, error.c_str());
		}

		fseek(f, 0, SEEK_END);
		len = ftell(f);
		fseek(f, 0, SEEK_SET);
		char* buf = new char[len + 1];

		if (fread(buf, 1, len, f) != len)
		{
			delete[] buf;
			fclose(f);
			std::string error("File i/o error reading index file ");
			error.append(filename);
			TCU_THROW(ResourceError, error.c_str());
		}

		buf[len] = 0;
		fclose(f);
		return buf;
	}

public:
	AmberIndexFileParser (const char* filename, const char* category)
	{
		std::string	indexFilename("vulkan/amber/");
		indexFilename.append(category);
		indexFilename.append("/");
		indexFilename.append(filename);

		m_buf = loadFile(indexFilename.c_str(), m_len);
		m_idx = 0;
	}

	~AmberIndexFileParser (void)
	{
		delete[] m_buf;
	}

	AmberTestCase* parse (const char* category, tcu::TestContext& testCtx)
	{
		// Format:
		// {"filename","test name","description"[,requirement[,requirement[,requirement..]]]}[,]
		// Things inside [] are optional. Whitespace is allowed everywhere.
		//
		// For example, test without requirements might be:
		// {"testname.amber","test name","test description"},

		if (m_idx < m_len)
		{
			skipWhitespace();
			expect('{');
			skipWhitespace();
			expect('"');
			captureString(m_filenameField);
			skipWhitespace();
			expect(',');
			skipWhitespace();
			expect('"');
			captureString(m_testnameField);
			skipWhitespace();
			expect(',');
			skipWhitespace();
			expect('"');
			captureString(m_descField);
			skipWhitespace();

			std::string testFilename("vulkan/amber/");
			testFilename.append(category);
			testFilename.append("/");
			testFilename.append(m_filenameField);
			AmberTestCase *testCase = new AmberTestCase(testCtx, m_testnameField, m_descField, testFilename);

			while (m_idx < m_len && m_buf[m_idx] == ',')
			{
				accept(',');
				skipWhitespace();
				expect('"');
				captureString(m_scratch);
				skipWhitespace();
				testCase->addRequirement(m_scratch);
			}

			expect('}');
			skipWhitespace();
			accept(',');
			skipWhitespace();
			return testCase;
		}
		return 0;
	}
};

void createAmberTestsFromIndexFile (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string filename, const char* category)
{
	AmberTestCase*			testCase = 0;
	AmberIndexFileParser	parser(filename.c_str(), category);

	do
	{
		testCase = parser.parse(category, testCtx);
		if (testCase)
		{
			group->addChild(testCase);
		}
	} while (testCase);
}

AmberTestCase* createAmberTestCase (tcu::TestContext&				testCtx,
									const char*						name,
									const char*						description,
									const char*						category,
									const std::string&				filename,
									const std::vector<std::string>	requirements)
{
	// shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
	std::string readFilename("vulkan/amber/");
	readFilename.append(category);
	readFilename.append("/");
	readFilename.append(filename);

	AmberTestCase *testCase = new AmberTestCase(testCtx, name, description, readFilename);

	for (auto req : requirements)
		testCase->addRequirement(req);

	return testCase;
}

} // cts_amber
} // vkt
<commit_msg>Fix amber index parser for archive dir<commit_after>/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 Google LLC
 * Copyright (c) 2019 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*--------------------------------------------------------------------*/

#include "vktAmberTestCase.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "tcuResource.hpp"

namespace vkt
{
namespace cts_amber
{

class AmberIndexFileParser
{
	std::string			m_str;
	size_t				m_idx;
	size_t				m_len;
	static const int	m_fieldLen = 256;
	char				m_scratch[m_fieldLen];
	char				m_filenameField[m_fieldLen];
	char				m_testnameField[m_fieldLen];
	char				m_descField[m_fieldLen];

	bool isWhitespace (char c)
	{
		if (c == ' '  ||
			c == '\t' ||
			c == '\r' ||
			c == '\n')
		{
			return true;
		}
		return false;
	}

	void skipWhitespace (void)
	{
		while (m_idx < m_len && isWhitespace(m_str[m_idx]))
			m_idx++;
	}

	void accept (char c)
	{
		if (m_str[m_idx] == c)
			m_idx++;
	}

	void expect (char c)
	{
		if (m_str[m_idx] != c || m_idx >= m_len)
			TCU_THROW(ResourceError, "Error parsing amber index file");

		m_idx++;
	}

	void captureString (char* field)
	{
		int i = 0;

		while (m_idx < m_len && i < m_fieldLen && m_str[m_idx] != '"')
		{
			field[i] = m_str[m_idx];
			i++;
			m_idx++;
		}

		field[i] = 0;
		m_idx++;
	}

public:
	AmberIndexFileParser (tcu::TestContext& testCtx, const char* filename, const char* category)
	{
		std::string	indexFilename("vulkan/amber/");
		indexFilename.append(category);
		indexFilename.append("/");
		indexFilename.append(filename);

		m_str = ShaderSourceProvider::getSource(testCtx.getArchive(), indexFilename.c_str());
		m_len = m_str.length();
		m_idx = 0;
	}

	~AmberIndexFileParser (void) { }

	AmberTestCase* parse (const char* category, tcu::TestContext& testCtx)
	{
		// Format:
		// {"filename","test name","description"[,requirement[,requirement[,requirement..]]]}[,]
		// Things inside [] are optional. Whitespace is allowed everywhere.
		//
		// For example, test without requirements might be:
		// {"testname.amber","test name","test description"},

		if (m_idx < m_len)
		{
			skipWhitespace();
			expect('{');
			skipWhitespace();
			expect('"');
			captureString(m_filenameField);
			skipWhitespace();
			expect(',');
			skipWhitespace();
			expect('"');
			captureString(m_testnameField);
			skipWhitespace();
			expect(',');
			skipWhitespace();
			expect('"');
			captureString(m_descField);
			skipWhitespace();

			std::string testFilename("vulkan/amber/");
			testFilename.append(category);
			testFilename.append("/");
			testFilename.append(m_filenameField);
			AmberTestCase *testCase = new AmberTestCase(testCtx, m_testnameField, m_descField, testFilename);

			while (m_idx < m_len && m_str[m_idx] == ',')
			{
				accept(',');
				skipWhitespace();
				expect('"');
				captureString(m_scratch);
				skipWhitespace();
				testCase->addRequirement(m_scratch);
			}

			expect('}');
			skipWhitespace();
			accept(',');
			skipWhitespace();
			return testCase;
		}
		return 0;
	}
};

void createAmberTestsFromIndexFile (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string filename, const char* category)
{
	AmberTestCase*			testCase = 0;
	AmberIndexFileParser	parser(testCtx, filename.c_str(), category);

	do
	{
		testCase = parser.parse(category, testCtx);
		if (testCase)
		{
			group->addChild(testCase);
		}
	} while (testCase);
}

AmberTestCase* createAmberTestCase (tcu::TestContext&				testCtx,
									const char*						name,
									const char*						description,
									const char*						category,
									const std::string&				filename,
									const std::vector<std::string>	requirements)
{
	// shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
	std::string readFilename("vulkan/amber/");
	readFilename.append(category);
	readFilename.append("/");
	readFilename.append(filename);

	AmberTestCase *testCase = new AmberTestCase(testCtx, name, description, readFilename);

	for (auto req : requirements)
		testCase->addRequirement(req);

	return testCase;
}

} // cts_amber
} // vkt
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
#define PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

#include "pcl/filters/statistical_outlier_removal.h"

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
  if (std_mul_ == 0.0)
  {
    PCL_ERROR ("[pcl::%s::applyFilter] Standard deviation multiplier not set!\n", getClassName ().c_str ());
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Initialize the spatial locator
  //initTree (spatial_locator_type_, tree_, k_);

  // TODO: fix this
  tree_.reset (new KdTreeFLANN<PointT> ());

  // Send the input dataset to the spatial locator
  tree_->setInputCloud (input_);

  // Allocate enough space to hold the results
  std::vector<int> nn_indices (mean_k_);
  std::vector<float> nn_dists (mean_k_);

  std::vector<float> distances (indices_->size ());
  // Go over all the points and calculate the mean or smallest distance
  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (!pcl_isfinite (input_->points[(*indices_)[cp]].x) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].y) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].z))
    {
      distances[cp] = 0;
      continue;
    }

    if (tree_->nearestKSearch ((*indices_)[cp], mean_k_, nn_indices, nn_dists) == 0)
    {
      distances[cp] = 0;
      PCL_WARN ("[pcl::%s::applyFilter] Searching for the closest %d neighbors failed.\n", getClassName ().c_str (), mean_k_);
      continue;
    }

    // Minimum distance (if mean_k_ == 2) or mean distance
    double dist_sum = 0;
    for (int j = 1; j < mean_k_; ++j)
      dist_sum += sqrt (nn_dists[j]);
    distances[cp] = dist_sum / (mean_k_-1);
  }

  // Estimate the mean and the standard deviation of the distance vector
  double mean, stddev;
  getMeanStd (distances, mean, stddev);
  double distance_threshold = mean + std_mul_ * stddev; // a distance that is bigger than this signals an outlier

  output.points.resize (input_->points.size ());      // reserve enough space
  removed_indices_->resize (input_->points.size ());

  // Build a new cloud by neglecting outliers
  int nr_p = 0;
  int nr_removed_p = 0;

  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (negative_)
    {
      if (distances[cp] <= distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }
    else
    {
      if (distances[cp] > distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }

    output.points[nr_p++] = input_->points[(*indices_)[cp]];
  }

  output.points.resize (nr_p);
  output.width  = nr_p;
  output.height = 1;
  output.is_dense = true; // nearestKSearch filters invalid points

  removed_indices_->resize (nr_removed_p);
}

#define PCL_INSTANTIATE_StatisticalOutlierRemoval(T) template class PCL_EXPORTS pcl::StatisticalOutlierRemoval<T>;

#endif    // PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

<commit_msg>we do not care for the results to be sorted when using StatisticalAnalysis outlier removal<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
#define PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

#include "pcl/filters/statistical_outlier_removal.h"

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
  if (std_mul_ == 0.0)
  {
    PCL_ERROR ("[pcl::%s::applyFilter] Standard deviation multiplier not set!\n", getClassName ().c_str ());
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Initialize the spatial locator
  //initTree (spatial_locator_type_, tree_, k_);

  // TODO: fix this
  tree_.reset (new KdTreeFLANN<PointT> (false));

  // Send the input dataset to the spatial locator
  tree_->setInputCloud (input_);

  // Allocate enough space to hold the results
  std::vector<int> nn_indices (mean_k_);
  std::vector<float> nn_dists (mean_k_);

  std::vector<float> distances (indices_->size ());
  // Go over all the points and calculate the mean or smallest distance
  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (!pcl_isfinite (input_->points[(*indices_)[cp]].x) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].y) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].z))
    {
      distances[cp] = 0;
      continue;
    }

    if (tree_->nearestKSearch ((*indices_)[cp], mean_k_, nn_indices, nn_dists) == 0)
    {
      distances[cp] = 0;
      PCL_WARN ("[pcl::%s::applyFilter] Searching for the closest %d neighbors failed.\n", getClassName ().c_str (), mean_k_);
      continue;
    }

    // Minimum distance (if mean_k_ == 2) or mean distance
    double dist_sum = 0;
    for (int j = 1; j < mean_k_; ++j)
      dist_sum += sqrt (nn_dists[j]);
    distances[cp] = dist_sum / (mean_k_-1);
  }

  // Estimate the mean and the standard deviation of the distance vector
  double mean, stddev;
  getMeanStd (distances, mean, stddev);
  double distance_threshold = mean + std_mul_ * stddev; // a distance that is bigger than this signals an outlier

  output.points.resize (input_->points.size ());      // reserve enough space
  removed_indices_->resize (input_->points.size ());

  // Build a new cloud by neglecting outliers
  int nr_p = 0;
  int nr_removed_p = 0;

  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (negative_)
    {
      if (distances[cp] <= distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }
    else
    {
      if (distances[cp] > distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }

    output.points[nr_p++] = input_->points[(*indices_)[cp]];
  }

  output.points.resize (nr_p);
  output.width  = nr_p;
  output.height = 1;
  output.is_dense = true; // nearestKSearch filters invalid points

  removed_indices_->resize (nr_removed_p);
}

#define PCL_INSTANTIATE_StatisticalOutlierRemoval(T) template class PCL_EXPORTS pcl::StatisticalOutlierRemoval<T>;

#endif    // PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

<|endoftext|>


<commit_before>#include "Green_Enemy.h"
#include"j1Enemy.h"
#include<math.h>
#include"j1Map.h"
#include"j1Pathfinding.h"
#include"j1Player.h"
Green_Enemy::Green_Enemy():Enemy(enemyType::green_enemy)
{
	this->sprites_vector = App->enemy->enemy_perf->sprites_vector;
	this->entity_texture = App->enemy->enemy_perf->entity_texture;
	this->ChangeAnimation(1);
}
Green_Enemy::Green_Enemy(const Green_Enemy& g_enemy) :Enemy(enemyType::green_enemy)
{
	this->collider = g_enemy.collider;
	this->logic_height = g_enemy.logic_height;
	this->sprites_vector = App->enemy->enemy_perf->sprites_vector;

}

Green_Enemy::~Green_Enemy()
{
}

void Green_Enemy::Action()
{
	tile_pos.x = pix_world_pos.x / 16;
	tile_pos.y = pix_world_pos.y / 16;
	if (player_in_range == nullptr) {
		iPoint actual_tile = pix_world_pos;
		if (passedtile == true) {
			temp_point = array_pos;
			array_pos = App->enemy->CalculatePath(this);
			if (array_pos == temp_point) {
				Path_Enemy.clear();
			}

		}

		int x = ((array_pos.x) - temp_point.x);

		int y = ((array_pos.y) - temp_point.y);

		pix_world_pos.x += x;
		pix_world_pos.y += y;

		if (x == 1) {
			Enemy_Orientation = OrientationEnemy::right_enemy;
		}
		else if (x == -1) {
			Enemy_Orientation = OrientationEnemy::left_enemy;
		}
		else if (y == 1) {
			Enemy_Orientation = OrientationEnemy::down_enemy;
		}
		else if (y == -1) {
			Enemy_Orientation = OrientationEnemy::up_enemy;
		}

		if ((actual_tile.x / 16) == array_pos.x && (actual_tile.y / 16) == array_pos.y) {
			passedtile = true;
		}
		else {
			passedtile = false;
		}
	}
	else {

	}
}

void Green_Enemy::Rang_Player()
{

	iPoint dist;
	dist.x = App->player->Link->pos.x - this->pix_world_pos.x;
	dist.y = App->player->Link->pos.y - this->pix_world_pos.y;
	iPoint dist2;
	dist2.x = App->player->Zelda->pos.x - pix_world_pos.x;
	dist2.y = App->player->Zelda->pos.y - pix_world_pos.y;

		if (sqrt((dist.x*dist.x) + (dist.y*dist.y)) < RANG && enemy_doing_script==false) {
			player_in_range = App->player->Link;
			//green_enemy_path.clear();
			if (tile_pos != iPoint(0, 0)) {
				if (App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos) != nullptr) {
					green_enemy_path = *App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos);
				}
				if (green_enemy_path.size()) {
					App->pathfinding->Move(this, player_in_range);
				}
			}
		}

		else if (sqrt((dist2.x*dist2.x) + (dist2.y*dist2.y)) < RANG  && enemy_doing_script == false) {
			player_in_range = App->player->Zelda;
			//green_enemy_path.clear();
			if (tile_pos != iPoint(0, 0)) {
				if (App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos) != nullptr) {
					green_enemy_path = *App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos);
				}
				if (green_enemy_path.size()) {
					App->pathfinding->Move(this, player_in_range);
				}
			}
		}

	/*
		else {
			player_in_range = nullptr;
			//App->pathfinding->last_path.clear();
			green_enemy_path.clear();
		}
		*/

}

<commit_msg>Enemies don't follow player if is in second level<commit_after>#include "Green_Enemy.h"
#include"j1Enemy.h"
#include<math.h>
#include"j1Map.h"
#include"j1Pathfinding.h"
#include"j1Player.h"
Green_Enemy::Green_Enemy():Enemy(enemyType::green_enemy)
{
	this->sprites_vector = App->enemy->enemy_perf->sprites_vector;
	this->entity_texture = App->enemy->enemy_perf->entity_texture;
	this->ChangeAnimation(1);
}
Green_Enemy::Green_Enemy(const Green_Enemy& g_enemy) :Enemy(enemyType::green_enemy)
{
	this->collider = g_enemy.collider;
	this->logic_height = g_enemy.logic_height;
	this->sprites_vector = App->enemy->enemy_perf->sprites_vector;

}

Green_Enemy::~Green_Enemy()
{
}

void Green_Enemy::Action()
{
	tile_pos.x = pix_world_pos.x / 16;
	tile_pos.y = pix_world_pos.y / 16;
	if (player_in_range == nullptr) {
		iPoint actual_tile = pix_world_pos;
		if (passedtile == true) {
			temp_point = array_pos;
			array_pos = App->enemy->CalculatePath(this);
			if (array_pos == temp_point) {
				Path_Enemy.clear();
			}

		}

		int x = ((array_pos.x) - temp_point.x);

		int y = ((array_pos.y) - temp_point.y);

		pix_world_pos.x += x;
		pix_world_pos.y += y;

		if (x == 1) {
			Enemy_Orientation = OrientationEnemy::right_enemy;
		}
		else if (x == -1) {
			Enemy_Orientation = OrientationEnemy::left_enemy;
		}
		else if (y == 1) {
			Enemy_Orientation = OrientationEnemy::down_enemy;
		}
		else if (y == -1) {
			Enemy_Orientation = OrientationEnemy::up_enemy;
		}

		if ((actual_tile.x / 16) == array_pos.x && (actual_tile.y / 16) == array_pos.y) {
			passedtile = true;
		}
		else {
			passedtile = false;
		}
	}
	else {

	}
}

void Green_Enemy::Rang_Player()
{

	iPoint dist;
	dist.x = App->player->Link->pos.x - this->pix_world_pos.x;
	dist.y = App->player->Link->pos.y - this->pix_world_pos.y;
	iPoint dist2;
	dist2.x = App->player->Zelda->pos.x - pix_world_pos.x;
	dist2.y = App->player->Zelda->pos.y - pix_world_pos.y;

		if (sqrt((dist.x*dist.x) + (dist.y*dist.y)) < RANG && enemy_doing_script==false) {
			player_in_range = App->player->Link;
			//green_enemy_path.clear();
			if (tile_pos != iPoint(0, 0)) {
				if (App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos) != nullptr && player_in_range->GetLogicHeightPlayer()==0) {
					green_enemy_path = *App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos);
				}
				if (green_enemy_path.size()) {
					App->pathfinding->Move(this, player_in_range);
				}
			}
		}

		else if (sqrt((dist2.x*dist2.x) + (dist2.y*dist2.y)) < RANG  && enemy_doing_script == false) {
			player_in_range = App->player->Zelda;
			//green_enemy_path.clear();
			if (tile_pos != iPoint(0, 0)) {
				if (App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos) != nullptr && player_in_range->GetLogicHeightPlayer() == 0) {
					green_enemy_path = *App->pathfinding->SimpleAstar(tile_pos, player_in_range->tilepos);
				}
				if (green_enemy_path.size()) {
					App->pathfinding->Move(this, player_in_range);
				}
			}
		}

	/*
		else {
			player_in_range = nullptr;
			//App->pathfinding->last_path.clear();
			green_enemy_path.clear();
		}
		*/

}

<|endoftext|>


<commit_before>// The rule of zero

#include <memory>
#include <vector>

class foo
{
	private:
		int x = 10;
		std::vector<int> v = {1, 2, 3, 4, 5};
};

class bar
{
	public:
		std::unique_ptr<int> p = std::make_unique<int>(5);
};

// Utilise the value semantics of existing types to avoid having to
// implement custom copy and move operations.
//
// The *rule of zero* states that we can avoid writing any custom
// copy/move constructors, assignment operators, or destructors by
// using existing types that support the appropriate copy/move
// semantics.
//
// The class `foo` on [6-11], for example, does not perform any
// manual memory management, yet correctly supports copies and
// moves without any memory leaks. The defaulted copy/move
// constructors and assignment operators will simply copy or move
// each member. For the `int` `x` ([9]), this will copy its value.
// For `v` ([10]), which is a [`std::vector`](cpp/container/vector),
// all of its elements will be copied over.
//
// The class `bar` on [13-17] is not copyable by default because it
// has a [`std::unique_ptr`](cpp/memory/unique_ptr) member which
// itself is not copyable. However, it correctly supports move
// operations, which will transfer ownership of the dynamically
// allocated resource.

int main()
{
	foo f1;
	foo f2 = f1;

	bar b1;
	bar b2 = std::move(b2);
}
<commit_msg>Fix bug in rule of zero sample<commit_after>// The rule of zero

#include <memory>
#include <vector>

class foo
{
	private:
		int x = 10;
		std::vector<int> v = {1, 2, 3, 4, 5};
};

class bar
{
	public:
		std::unique_ptr<int> p = std::make_unique<int>(5);
};

// Utilise the value semantics of existing types to avoid having to
// implement custom copy and move operations.
//
// The *rule of zero* states that we can avoid writing any custom
// copy/move constructors, assignment operators, or destructors by
// using existing types that support the appropriate copy/move
// semantics.
//
// The class `foo` on [6-11], for example, does not perform any
// manual memory management, yet correctly supports copies and
// moves without any memory leaks. The defaulted copy/move
// constructors and assignment operators will simply copy or move
// each member. For the `int` `x` ([9]), this will copy its value.
// For `v` ([10]), which is a [`std::vector`](cpp/container/vector),
// all of its elements will be copied over.
//
// The class `bar` on [13-17] is not copyable by default because it
// has a [`std::unique_ptr`](cpp/memory/unique_ptr) member which
// itself is not copyable. However, it correctly supports move
// operations, which will transfer ownership of the dynamically
// allocated resource.

int main()
{
	foo f1;
	foo f2 = f1;

	bar b1;
	bar b2 = std::move(b1);
}
<|endoftext|>


<commit_before>/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include <string>
#include <iostream>

#include <boost/scoped_ptr.hpp>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>

#include <chemkit/chemkit.h>
#include <chemkit/moleculefile.h>

void printHelp(char *argv[], const boost::program_options::options_description &options)
{
    std::cout << "Usage: " << argv[0] << " [OPTIONS] inputFile outputFile\n";
    std::cout << "\n";
    std::cout << "Converts a chemical input file to a new file with\n";
    std::cout << "a different file format.\n";
    std::cout << "\n";
    std::cout << "Options:\n";
    std::cout << options << "\n";
}

int main(int argc, char *argv[])
{
    std::string inputFileName;
    std::string inputFormatName;
    std::string outputFileName;
    std::string outputFormatName;

    boost::program_options::options_description options;
    options.add_options()
        ("input-file",
            boost::program_options::value<std::string>(&inputFileName),
            "The input file.")
        ("output-file",
            boost::program_options::value<std::string>(&outputFileName),
            "The output file.")
        ("input-format,i",
            boost::program_options::value<std::string>(&inputFormatName),
            "Sets the input format.")
        ("output-format,o",
            boost::program_options::value<std::string>(&outputFormatName),
            "Sets the output format.")
        ("help,h",
            "Shows this help message");

    boost::program_options::positional_options_description positionalOptions;
    positionalOptions.add("input-file", 1).add("output-file", 1);

    boost::program_options::variables_map variables;
    boost::program_options::store(
        boost::program_options::command_line_parser(argc, argv)
            .options(options)
            .positional(positionalOptions).run(),
        variables);
    boost::program_options::notify(variables);

    if(variables.count("help")){
        printHelp(argv, options);
        return 0;
    }
    else if(inputFileName.empty()){
        printHelp(argv, options);
        std::cerr << "Error: No input file specified." << std::endl;
        return -1;
    }
    else if(outputFileName.empty()){
        printHelp(argv, options);
        std::cerr << "Error: No output file specified." << std::endl;
        return -1;
    }

    // read input
    chemkit::MoleculeFile inputFile(inputFileName);
    if(!inputFormatName.empty()){
        inputFile.setFormat(inputFormatName);
    }

    bool ok = inputFile.read();
    if(!ok){
        std::cerr << "Error: Failed to read input file: " << inputFile.errorString() << std::endl;
        return -1;
    }

    // write output
    if(outputFormatName.empty()){
        ok = inputFile.write(outputFileName);
    }
    else{
        ok = inputFile.write(outputFileName, outputFormatName);
    }

    if(!ok){
        std::cerr << "Error: failed to write output file: " << inputFile.errorString() << std::endl;
        return -1;
    }

    return 0;
}
<commit_msg>Add support for using stdin/stdout in chemkit-convert<commit_after>/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include <string>
#include <iostream>

#include <boost/scoped_ptr.hpp>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>

#include <chemkit/chemkit.h>
#include <chemkit/moleculefile.h>

void printHelp(char *argv[], const boost::program_options::options_description &options)
{
    std::cout << "Usage: " << argv[0] << " [OPTIONS] inputFile outputFile\n";
    std::cout << "\n";
    std::cout << "Converts a chemical input file to a new file with\n";
    std::cout << "a different file format.\n";
    std::cout << "\n";
    std::cout << "Options:\n";
    std::cout << options << "\n";
}

int main(int argc, char *argv[])
{
    std::string inputFileName;
    std::string inputFormatName;
    std::string outputFileName;
    std::string outputFormatName;

    boost::program_options::options_description options;
    options.add_options()
        ("input-file",
            boost::program_options::value<std::string>(&inputFileName),
            "The input file.")
        ("output-file",
            boost::program_options::value<std::string>(&outputFileName),
            "The output file.")
        ("input-format,i",
            boost::program_options::value<std::string>(&inputFormatName),
            "Sets the input format.")
        ("output-format,o",
            boost::program_options::value<std::string>(&outputFormatName),
            "Sets the output format.")
        ("help,h",
            "Shows this help message");

    boost::program_options::positional_options_description positionalOptions;
    positionalOptions.add("input-file", 1).add("output-file", 1);

    boost::program_options::variables_map variables;
    boost::program_options::store(
        boost::program_options::command_line_parser(argc, argv)
            .options(options)
            .positional(positionalOptions).run(),
        variables);
    boost::program_options::notify(variables);

    if(variables.count("help")){
        printHelp(argv, options);
        return 0;
    }
    else if(inputFileName.empty()){
        printHelp(argv, options);
        std::cerr << "Error: No input file specified." << std::endl;
        return -1;
    }
    else if(outputFileName.empty()){
        printHelp(argv, options);
        std::cerr << "Error: No output file specified." << std::endl;
        return -1;
    }

    // read input
    chemkit::MoleculeFile inputFile;
    if(!inputFormatName.empty()){
        inputFile.setFormat(inputFormatName);
    }

    bool ok = false;
    if(inputFileName == "-"){
        ok = inputFile.read(std::cin);
    }
    else{
        ok = inputFile.read(inputFileName);
    }

    if(!ok){
        std::cerr << "Error: Failed to read input file: " << inputFile.errorString() << std::endl;
        return -1;
    }

    // write output
    if(outputFormatName.empty()){
        ok = inputFile.write(outputFileName);
    }
    else{
        if(outputFileName == "-"){
            ok = inputFile.write(std::cout, outputFormatName);
        }
        else{
            ok = inputFile.write(outputFileName, outputFormatName);
        }
    }

    if(!ok){
        std::cerr << "Error: failed to write output file: " << inputFile.errorString() << std::endl;
        return -1;
    }

    return 0;
}
<|endoftext|>