<commit_before>#include <vigra/multi_distance.hxx>
#include <vigra/impex.hxx>

#include <util/Logger.h>
#include "DistanceToleranceFunction.h"

logger::LogChannel distancetolerancelog("distancetolerancelog", "[DistanceToleranceFunction] ");

DistanceToleranceFunction::DistanceToleranceFunction(
		float distanceThreshold,
		bool haveBackgroundLabel,
		float backgroundLabel) :
	_maxDistanceThreshold(distanceThreshold),
	_haveBackgroundLabel(haveBackgroundLabel),
	_backgroundLabel(backgroundLabel) {

	_resolutionX = 4.0;
	_resolutionY = 4.0;
	_resolutionZ = 40.0;
}

void
DistanceToleranceFunction::extractCells(
		unsigned int numCells,
		const vigra::MultiArray<3, unsigned int>& cellLabels,
		const ImageStack& recLabels,
		const ImageStack& gtLabels) {

	_depth  = gtLabels.size();
	_width  = gtLabels.width();
	_height = gtLabels.height();

	createBoundaryMap(recLabels);
	createBoundaryDistanceMap();

	// create a cell for each found connected component in cellLabels
	_cells->resize(numCells);

	// the maximum boundary distance of any location for each cell
	std::vector<float> maxBoundaryDistances(numCells, 0);

	std::set<unsigned int> foundCells;
	for (unsigned int z = 0; z < _depth; z++) {

		boost::shared_ptr<const Image> gt  = gtLabels[z];
		boost::shared_ptr<const Image> rec = recLabels[z];

		for (unsigned int x = 0; x < _width; x++)
			for (unsigned int y = 0; y < _height; y++) {

				float gtLabel  = (*gt)(x, y);
				float recLabel = (*rec)(x, y);

				// argh, vigra starts counting at 1!
				unsigned int cellIndex = cellLabels(x, y, z) - 1;

				(*_cells)[cellIndex].add(cell_t::Location(x, y, z));
				(*_cells)[cellIndex].setReconstructionLabel(recLabel);
				(*_cells)[cellIndex].setGroundTruthLabel(gtLabel);

				maxBoundaryDistances[cellIndex] = std::max(maxBoundaryDistances[cellIndex], _boundaryDistance2(x, y, z));

				if (foundCells.count(cellIndex) == 0) {

					registerPossibleMatch(gtLabel, recLabel);
					foundCells.insert(cellIndex);
				}
			}
	}

	for (unsigned int cellIndex = 0; cellIndex < numCells; cellIndex++)
		if (maxBoundaryDistances[cellIndex] < _maxDistanceThreshold*_maxDistanceThreshold)
			_relabelCandidates.push_back(cellIndex);

	enumerateCellLabels(recLabels);
}

void
DistanceToleranceFunction::createBoundaryMap(const ImageStack& recLabels) {

	vigra::Shape3 shape(_width, _height, _depth);
	_boundaryMap.reshape(shape);

	// create boundary map
	LOG_DEBUG(distancetolerancelog) << "creating boundary map of size " << shape << std::endl;
	_boundaryMap = 0.0f;
	for (unsigned int x = 0; x < _width; x++)
		for (unsigned int y = 0; y < _height; y++)
			for (unsigned int z = 0; z < _depth; z++)
				if (isBoundaryVoxel(x, y, z, recLabels))
					_boundaryMap(x, y, z) = 1.0f;
}

void
DistanceToleranceFunction::createBoundaryDistanceMap() {

	vigra::Shape3 shape(_width, _height, _depth);
	_boundaryDistance2.reshape(shape);

	float pitch[3];
	pitch[0] = _resolutionX;
	pitch[1] = _resolutionY;
	pitch[2] = _resolutionZ;

	// compute l2 distance for each pixel to boundary
	LOG_DEBUG(distancetolerancelog) << "computing boundary distances" << std::endl;
	vigra::separableMultiDistSquared(
			_boundaryMap,
			_boundaryDistance2,
			true /* background */,
			pitch);
}

void
DistanceToleranceFunction::enumerateCellLabels(const ImageStack& recLabels) {

	_maxDistanceThresholdX = std::min((float)_width,  _maxDistanceThreshold/_resolutionX);
	_maxDistanceThresholdY = std::min((float)_height, _maxDistanceThreshold/_resolutionY);
	_maxDistanceThresholdZ = std::min((float)_depth,  _maxDistanceThreshold/_resolutionZ);

	LOG_DEBUG(distancetolerancelog) << "there are " << _relabelCandidates.size() << " cells that can be relabeled" << std::endl;

	if (_relabelCandidates.size() == 0)
		return;

	LOG_DEBUG(distancetolerancelog) << "creating distance threshold neighborhood" << std::endl;

	// list of all location offsets within threshold distance
	std::vector<cell_t::Location> neighborhood = createNeighborhood();

	LOG_DEBUG(distancetolerancelog) << "there are " << neighborhood.size() << " pixels in the neighborhood for a threshold of " << _maxDistanceThreshold << std::endl;

	// for each cell
	foreach (unsigned int index, _relabelCandidates) {

		cell_t& cell = (*_cells)[index];

		LOG_ALL(distancetolerancelog) << "processing cell " << index << " (label " << cell.getReconstructionLabel() << ")" << std::flush;

		std::set<float> alternativeLabels = getAlternativeLabels(cell, neighborhood, recLabels);

		// every cell that is small enough to be relabelled is allowed to change
		// to background label
		if (_haveBackgroundLabel)
			alternativeLabels.insert(_backgroundLabel);

		LOG_ALL(distancetolerancelog) << "; can map to ";

		// for each alternative label
		foreach (float recLabel, alternativeLabels) {

			LOG_ALL(distancetolerancelog) << recLabel << " ";

			// register possible match
			cell.addAlternativeLabel(recLabel);
			registerPossibleMatch(cell.getGroundTruthLabel(), recLabel);
		}
		LOG_ALL(distancetolerancelog) << std::endl;

		// DEBUG
		index++;
	}
}

bool
DistanceToleranceFunction::isBoundaryVoxel(int x, int y, int z, const ImageStack& stack) {

	float center = (*stack[z])(x, y);

	for (int dz = -1; dz <= 1; dz++)
		for (int dy = -1; dy <= 1; dy++)
			for (int dx = -1; dx <= 1; dx++)
				if (
						!(dx == 0 && dy == 0 && dz == 0) &&
						(x + dx) >= 0 && (x + dx) < (int)_width  &&
						(y + dy) >= 0 && (y + dy) < (int)_height &&
						(z + dz) >= 0 && (z + dz) < (int)_depth)

					if ((*stack[z + dz])(x + dx, y + dy) != center)
						return true;

	return false;
}

std::vector<DistanceToleranceFunction::cell_t::Location>
DistanceToleranceFunction::createNeighborhood() {

	std::vector<cell_t::Location> thresholdOffsets;

	// quick check first: test on all three axes -- if they contain all covering
	// labels already, we can abort iterating earlier in getAlternativeLabels()

	for (int z = 1; z <= _maxDistanceThresholdZ; z++) {

		thresholdOffsets.push_back(cell_t::Location(0, 0,  z));
		thresholdOffsets.push_back(cell_t::Location(0, 0, -z));
	}
	for (int y = 1; y <= _maxDistanceThresholdY; y++) {

		thresholdOffsets.push_back(cell_t::Location(0,  y, 0));
		thresholdOffsets.push_back(cell_t::Location(0, -y, 0));
	}
	for (int x = 1; x <= _maxDistanceThresholdX; x++) {

		thresholdOffsets.push_back(cell_t::Location( x, 0, 0));
		thresholdOffsets.push_back(cell_t::Location(-x, 0, 0));
	}

	for (int z = -_maxDistanceThresholdZ; z <= _maxDistanceThresholdZ; z++)
		for (int y = -_maxDistanceThresholdY; y <= _maxDistanceThresholdY; y++)
			for (int x = -_maxDistanceThresholdX; x <= _maxDistanceThresholdX; x++) {

				// axis locations have been added already, center is not needed
				if ((x == 0 && y == 0) || (x == 0 && z == 0) || (y == 0 && z == 0))
					continue;

				// is it within threshold distance?
				if (
						x*_resolutionX*x*_resolutionX +
						y*_resolutionY*y*_resolutionY +
						z*_resolutionZ*z*_resolutionZ <= _maxDistanceThreshold*_maxDistanceThreshold)

					thresholdOffsets.push_back(cell_t::Location(x, y, z));
			}

	return thresholdOffsets;
}

std::set<float>
DistanceToleranceFunction::getAlternativeLabels(
		const cell_t& cell,
		const std::vector<cell_t::Location>& neighborhood,
		const ImageStack& recLabels) {

	float cellLabel = cell.getReconstructionLabel();

	// counts for each neighbor label, how often it was found while iterating
	// over the cells locations
	std::map<float, unsigned int> counts;

	// the number of cell locations visited so far
	unsigned int numVisited = 0;

	// the maximal number of alternative labels, starts with number of labels
	// found at first location and decreases whenever one label was not found
	unsigned int maxAlternativeLabels = 0;

	// for each location i in that cell
	foreach (const cell_t::Location& i, cell) {

		// all the labels in the neighborhood of i
		std::set<float> neighborhoodLabels;

		numVisited++;

		// the number of complete neighbor labels that have been seen at the
		// current location
		unsigned int numComplete = 0;

		// for all locations within the neighborhood, get alternative labels
		foreach (const cell_t::Location& n, neighborhood) {

			cell_t::Location j(i.x + n.x, i.y + n.y, i.z + n.z);

			// are we leaving the image?
			if (j.x < 0 || j.x >= (int)_width || j.y < 0 || j.y >= (int)_height || j.z < 0 || j.z >= (int)_depth)
				continue;

			// is this a boundary?
			if (!_boundaryMap(j.x, j.y, j.z))
				continue;

			// now we have found a boundary pixel within our neighborhood
			float label = (*(recLabels)[j.z])(j.x, j.y);

			// count how often we see a neighbor label the first time
			if (label != cellLabel) {

				bool firstTime = neighborhoodLabels.insert(label).second;

				// seen the first time for the current location i
				if (firstTime)
					// is a potential alternative label (covers all visited
					// locations so far)
					if (++counts[label] == numVisited) {

						numComplete++;

						// if we have seen all the possible complete labels
						// already, there is no need to search further for the
						// current location i
						if (numComplete == maxAlternativeLabels)
							break;
					}
			}
		}

		// the number of labels that we have seen for each location visited so
		// far is the maximal possible number of alternative labels
		maxAlternativeLabels = numComplete;

		// none of the neighbor labels covers the cell
		if (maxAlternativeLabels == 0)
			break;
	}

	std::set<float> alternativeLabels;

	// collect all neighbor labels that we have seen for every location of the
	// cell
	float label;
	unsigned int count;
	foreach (boost::tie(label, count), counts)
		if (count == cell.size())
			alternativeLabels.insert(label);

	if (alternativeLabels.size() != maxAlternativeLabels)
		LOG_ERROR(distancetolerancelog) << "MAX ALTERNATIVE LABELS DOES NOT MATCH NUMBER OF LABELS FOUND!" << std::endl;

	return alternativeLabels;
}
<commit_msg>changed tolerance criterion to <= (was <) in DistanceToleranceFunction<commit_after>#include <vigra/multi_distance.hxx>
#include <vigra/impex.hxx>

#include <util/Logger.h>
#include "DistanceToleranceFunction.h"

logger::LogChannel distancetolerancelog("distancetolerancelog", "[DistanceToleranceFunction] ");

DistanceToleranceFunction::DistanceToleranceFunction(
		float distanceThreshold,
		bool haveBackgroundLabel,
		float backgroundLabel) :
	_maxDistanceThreshold(distanceThreshold),
	_haveBackgroundLabel(haveBackgroundLabel),
	_backgroundLabel(backgroundLabel) {

	_resolutionX = 4.0;
	_resolutionY = 4.0;
	_resolutionZ = 40.0;
}

void
DistanceToleranceFunction::extractCells(
		unsigned int numCells,
		const vigra::MultiArray<3, unsigned int>& cellLabels,
		const ImageStack& recLabels,
		const ImageStack& gtLabels) {

	_depth  = gtLabels.size();
	_width  = gtLabels.width();
	_height = gtLabels.height();

	createBoundaryMap(recLabels);
	createBoundaryDistanceMap();

	// create a cell for each found connected component in cellLabels
	_cells->resize(numCells);

	// the maximum boundary distance of any location for each cell
	std::vector<float> maxBoundaryDistances(numCells, 0);

	std::set<unsigned int> foundCells;
	for (unsigned int z = 0; z < _depth; z++) {

		boost::shared_ptr<const Image> gt  = gtLabels[z];
		boost::shared_ptr<const Image> rec = recLabels[z];

		for (unsigned int x = 0; x < _width; x++)
			for (unsigned int y = 0; y < _height; y++) {

				float gtLabel  = (*gt)(x, y);
				float recLabel = (*rec)(x, y);

				// argh, vigra starts counting at 1!
				unsigned int cellIndex = cellLabels(x, y, z) - 1;

				(*_cells)[cellIndex].add(cell_t::Location(x, y, z));
				(*_cells)[cellIndex].setReconstructionLabel(recLabel);
				(*_cells)[cellIndex].setGroundTruthLabel(gtLabel);

				maxBoundaryDistances[cellIndex] = std::max(maxBoundaryDistances[cellIndex], _boundaryDistance2(x, y, z));

				if (foundCells.count(cellIndex) == 0) {

					registerPossibleMatch(gtLabel, recLabel);
					foundCells.insert(cellIndex);
				}
			}
	}

	for (unsigned int cellIndex = 0; cellIndex < numCells; cellIndex++)
		if (maxBoundaryDistances[cellIndex] <= _maxDistanceThreshold*_maxDistanceThreshold)
			_relabelCandidates.push_back(cellIndex);

	enumerateCellLabels(recLabels);
}

void
DistanceToleranceFunction::createBoundaryMap(const ImageStack& recLabels) {

	vigra::Shape3 shape(_width, _height, _depth);
	_boundaryMap.reshape(shape);

	// create boundary map
	LOG_DEBUG(distancetolerancelog) << "creating boundary map of size " << shape << std::endl;
	_boundaryMap = 0.0f;
	for (unsigned int x = 0; x < _width; x++)
		for (unsigned int y = 0; y < _height; y++)
			for (unsigned int z = 0; z < _depth; z++)
				if (isBoundaryVoxel(x, y, z, recLabels))
					_boundaryMap(x, y, z) = 1.0f;
}

void
DistanceToleranceFunction::createBoundaryDistanceMap() {

	vigra::Shape3 shape(_width, _height, _depth);
	_boundaryDistance2.reshape(shape);

	float pitch[3];
	pitch[0] = _resolutionX;
	pitch[1] = _resolutionY;
	pitch[2] = _resolutionZ;

	// compute l2 distance for each pixel to boundary
	LOG_DEBUG(distancetolerancelog) << "computing boundary distances" << std::endl;
	vigra::separableMultiDistSquared(
			_boundaryMap,
			_boundaryDistance2,
			true /* background */,
			pitch);
}

void
DistanceToleranceFunction::enumerateCellLabels(const ImageStack& recLabels) {

	_maxDistanceThresholdX = std::min((float)_width,  _maxDistanceThreshold/_resolutionX);
	_maxDistanceThresholdY = std::min((float)_height, _maxDistanceThreshold/_resolutionY);
	_maxDistanceThresholdZ = std::min((float)_depth,  _maxDistanceThreshold/_resolutionZ);

	LOG_DEBUG(distancetolerancelog) << "there are " << _relabelCandidates.size() << " cells that can be relabeled" << std::endl;

	if (_relabelCandidates.size() == 0)
		return;

	LOG_DEBUG(distancetolerancelog) << "creating distance threshold neighborhood" << std::endl;

	// list of all location offsets within threshold distance
	std::vector<cell_t::Location> neighborhood = createNeighborhood();

	LOG_DEBUG(distancetolerancelog) << "there are " << neighborhood.size() << " pixels in the neighborhood for a threshold of " << _maxDistanceThreshold << std::endl;

	// for each cell
	foreach (unsigned int index, _relabelCandidates) {

		cell_t& cell = (*_cells)[index];

		LOG_ALL(distancetolerancelog) << "processing cell " << index << " (label " << cell.getReconstructionLabel() << ")" << std::flush;

		std::set<float> alternativeLabels = getAlternativeLabels(cell, neighborhood, recLabels);

		// every cell that is small enough to be relabelled is allowed to change
		// to background label
		if (_haveBackgroundLabel)
			alternativeLabels.insert(_backgroundLabel);

		LOG_ALL(distancetolerancelog) << "; can map to ";

		// for each alternative label
		foreach (float recLabel, alternativeLabels) {

			LOG_ALL(distancetolerancelog) << recLabel << " ";

			// register possible match
			cell.addAlternativeLabel(recLabel);
			registerPossibleMatch(cell.getGroundTruthLabel(), recLabel);
		}
		LOG_ALL(distancetolerancelog) << std::endl;

		// DEBUG
		index++;
	}
}

bool
DistanceToleranceFunction::isBoundaryVoxel(int x, int y, int z, const ImageStack& stack) {

	float center = (*stack[z])(x, y);

	for (int dz = -1; dz <= 1; dz++)
		for (int dy = -1; dy <= 1; dy++)
			for (int dx = -1; dx <= 1; dx++)
				if (
						!(dx == 0 && dy == 0 && dz == 0) &&
						(x + dx) >= 0 && (x + dx) < (int)_width  &&
						(y + dy) >= 0 && (y + dy) < (int)_height &&
						(z + dz) >= 0 && (z + dz) < (int)_depth)

					if ((*stack[z + dz])(x + dx, y + dy) != center)
						return true;

	return false;
}

std::vector<DistanceToleranceFunction::cell_t::Location>
DistanceToleranceFunction::createNeighborhood() {

	std::vector<cell_t::Location> thresholdOffsets;

	// quick check first: test on all three axes -- if they contain all covering
	// labels already, we can abort iterating earlier in getAlternativeLabels()

	for (int z = 1; z <= _maxDistanceThresholdZ; z++) {

		thresholdOffsets.push_back(cell_t::Location(0, 0,  z));
		thresholdOffsets.push_back(cell_t::Location(0, 0, -z));
	}
	for (int y = 1; y <= _maxDistanceThresholdY; y++) {

		thresholdOffsets.push_back(cell_t::Location(0,  y, 0));
		thresholdOffsets.push_back(cell_t::Location(0, -y, 0));
	}
	for (int x = 1; x <= _maxDistanceThresholdX; x++) {

		thresholdOffsets.push_back(cell_t::Location( x, 0, 0));
		thresholdOffsets.push_back(cell_t::Location(-x, 0, 0));
	}

	for (int z = -_maxDistanceThresholdZ; z <= _maxDistanceThresholdZ; z++)
		for (int y = -_maxDistanceThresholdY; y <= _maxDistanceThresholdY; y++)
			for (int x = -_maxDistanceThresholdX; x <= _maxDistanceThresholdX; x++) {

				// axis locations have been added already, center is not needed
				if ((x == 0 && y == 0) || (x == 0 && z == 0) || (y == 0 && z == 0))
					continue;

				// is it within threshold distance?
				if (
						x*_resolutionX*x*_resolutionX +
						y*_resolutionY*y*_resolutionY +
						z*_resolutionZ*z*_resolutionZ <= _maxDistanceThreshold*_maxDistanceThreshold)

					thresholdOffsets.push_back(cell_t::Location(x, y, z));
			}

	return thresholdOffsets;
}

std::set<float>
DistanceToleranceFunction::getAlternativeLabels(
		const cell_t& cell,
		const std::vector<cell_t::Location>& neighborhood,
		const ImageStack& recLabels) {

	float cellLabel = cell.getReconstructionLabel();

	// counts for each neighbor label, how often it was found while iterating
	// over the cells locations
	std::map<float, unsigned int> counts;

	// the number of cell locations visited so far
	unsigned int numVisited = 0;

	// the maximal number of alternative labels, starts with number of labels
	// found at first location and decreases whenever one label was not found
	unsigned int maxAlternativeLabels = 0;

	// for each location i in that cell
	foreach (const cell_t::Location& i, cell) {

		// all the labels in the neighborhood of i
		std::set<float> neighborhoodLabels;

		numVisited++;

		// the number of complete neighbor labels that have been seen at the
		// current location
		unsigned int numComplete = 0;

		// for all locations within the neighborhood, get alternative labels
		foreach (const cell_t::Location& n, neighborhood) {

			cell_t::Location j(i.x + n.x, i.y + n.y, i.z + n.z);

			// are we leaving the image?
			if (j.x < 0 || j.x >= (int)_width || j.y < 0 || j.y >= (int)_height || j.z < 0 || j.z >= (int)_depth)
				continue;

			// is this a boundary?
			if (!_boundaryMap(j.x, j.y, j.z))
				continue;

			// now we have found a boundary pixel within our neighborhood
			float label = (*(recLabels)[j.z])(j.x, j.y);

			// count how often we see a neighbor label the first time
			if (label != cellLabel) {

				bool firstTime = neighborhoodLabels.insert(label).second;

				// seen the first time for the current location i
				if (firstTime)
					// is a potential alternative label (covers all visited
					// locations so far)
					if (++counts[label] == numVisited) {

						numComplete++;

						// if we have seen all the possible complete labels
						// already, there is no need to search further for the
						// current location i
						if (numComplete == maxAlternativeLabels)
							break;
					}
			}
		}

		// the number of labels that we have seen for each location visited so
		// far is the maximal possible number of alternative labels
		maxAlternativeLabels = numComplete;

		// none of the neighbor labels covers the cell
		if (maxAlternativeLabels == 0)
			break;
	}

	std::set<float> alternativeLabels;

	// collect all neighbor labels that we have seen for every location of the
	// cell
	float label;
	unsigned int count;
	foreach (boost::tie(label, count), counts)
		if (count == cell.size())
			alternativeLabels.insert(label);

	if (alternativeLabels.size() != maxAlternativeLabels)
		LOG_ERROR(distancetolerancelog) << "MAX ALTERNATIVE LABELS DOES NOT MATCH NUMBER OF LABELS FOUND!" << std::endl;

	return alternativeLabels;
}
<|endoftext|>


<commit_before>#include "server.hpp"

using std::string;

Game::Game(unsigned int _bunch_num, unsigned int _bunch_den, unsigned int _player_limit)
	: player_limit(_player_limit)
{
	for (char ch = 'A'; ch <= 'Z'; ++ch)
		for (unsigned int i = 0; i < ((letter_count[ch - 'A'] * _bunch_num) / _bunch_den); ++i)
			random_insert(bunch, ch);

	auto it = bunch.begin();
	for (int i = 0; i < 20; ++i, ++it);
	bunch.erase(it, bunch.end());
}

Player& Game::add_player(const string& id, const sf::IpAddress& ip, unsigned short port, const string& name)
{
	players[id] = Player(ip, port, name);
	return players[id];
}

void Game::remove_player(const string& id)
{
	for (auto chr : players.at(id).get_hand())
		random_insert(bunch, chr);

	players.erase(id);

	if (playing)
	{
		if (players.size() < 2)
		{
			ready_to_finish = true;
			finished = true;

			// win by default
			if (players.size() > 0)
				winner = players.begin()->first;
		}
	}
	else
		try_to_start();
}

void Game::set_ready(const string& id, bool ready)
{
	if (!playing)
	{
		players.at(id).ready = ready;

		if (ready)
			try_to_start();
	}
}

// XXX assumes dump is valid!
string Game::dump(const string& id, const sf::Int16& dump_n, char chr)
{
	if (dump_n == players.at(id).get_dump() - 1)
		return players.at(id).last_dump();
	else if (dump_n == players.at(id).get_dump())
	{
		string letters;

		if (bunch.size() >= 3)
		{
			// take three
			for (unsigned int i = 0; i < 3; ++i)
			{
				letters.append(1, bunch.back());
				bunch.pop_back();
			}
			players.at(id).give_dump(chr, letters);

			random_insert(bunch, chr);
		}
		else
			letters.append(1, chr);

		return letters;
	}

	// XXX should never get here!!!
	return "";
}

// XXX assumes peeling is valid. returns true if game has ended
bool Game::peel()
{
	// if there aren't enough letters left
	if (bunch.size() < players.size())
	{
		ready_to_finish = true;
		finished = true;
		return true;
	}

	unsigned int num_letters = 1;
	ready_to_peel = false;

	// if this is the first peel
	if (peel_number++ == 0)
	{
		playing = true;
		num_letters = 10; // TODO calculate

		// reset ack counters to track peels
		for (auto& pair : players)
			pair.second.reset_ack();
	}

	for (auto& pair : players)
	{
		string letters;
		for (unsigned int i = 0; i < num_letters; ++i)
		{
			letters.append(1, bunch.back());
			bunch.pop_back();
		}

		pair.second.give_peel(letters);
	}

	return false;
}

void Game::try_to_start()
{
	// if already started
	if (playing)
		return;

	// if not enough players
	if (players.size() < 2)
		return;

	// if players aren't ready
	for (const auto& pair : players)
		if (!pair.second.ready)
			return;

	ready_to_peel = true;
}

void Game::check_waiting()
{
	for (const auto& pair : players)
		if (pair.second.has_pending())
			return;

	waiting = false;
}
<commit_msg>Fix out of range error when all players leave<commit_after>#include "server.hpp"

using std::string;

Game::Game(unsigned int _bunch_num, unsigned int _bunch_den, unsigned int _player_limit)
	: player_limit(_player_limit)
{
	for (char ch = 'A'; ch <= 'Z'; ++ch)
		for (unsigned int i = 0; i < ((letter_count[ch - 'A'] * _bunch_num) / _bunch_den); ++i)
			random_insert(bunch, ch);

	auto it = bunch.begin();
	for (int i = 0; i < 20; ++i, ++it);
	bunch.erase(it, bunch.end());
}

Player& Game::add_player(const string& id, const sf::IpAddress& ip, unsigned short port, const string& name)
{
	players[id] = Player(ip, port, name);
	return players[id];
}

void Game::remove_player(const string& id)
{
	for (auto chr : players.at(id).get_hand())
		random_insert(bunch, chr);

	players.erase(id);

	if (playing)
	{
		if (players.size() < 2)
		{
			ready_to_finish = true;
			finished = true;

			// win by default
			if (players.size() > 0)
				winner = players.begin()->first;
			else
				winner.clear();
		}
	}
	else
		try_to_start();
}

void Game::set_ready(const string& id, bool ready)
{
	if (!playing)
	{
		players.at(id).ready = ready;

		if (ready)
			try_to_start();
	}
}

// XXX assumes dump is valid!
string Game::dump(const string& id, const sf::Int16& dump_n, char chr)
{
	if (dump_n == players.at(id).get_dump() - 1)
		return players.at(id).last_dump();
	else if (dump_n == players.at(id).get_dump())
	{
		string letters;

		if (bunch.size() >= 3)
		{
			// take three
			for (unsigned int i = 0; i < 3; ++i)
			{
				letters.append(1, bunch.back());
				bunch.pop_back();
			}
			players.at(id).give_dump(chr, letters);

			random_insert(bunch, chr);
		}
		else
			letters.append(1, chr);

		return letters;
	}

	// XXX should never get here!!!
	return "";
}

// XXX assumes peeling is valid. returns true if game has ended
bool Game::peel()
{
	// if there aren't enough letters left
	if (bunch.size() < players.size())
	{
		ready_to_finish = true;
		finished = true;
		return true;
	}

	unsigned int num_letters = 1;
	ready_to_peel = false;

	// if this is the first peel
	if (peel_number++ == 0)
	{
		playing = true;
		num_letters = 10; // TODO calculate

		// reset ack counters to track peels
		for (auto& pair : players)
			pair.second.reset_ack();
	}

	for (auto& pair : players)
	{
		string letters;
		for (unsigned int i = 0; i < num_letters; ++i)
		{
			letters.append(1, bunch.back());
			bunch.pop_back();
		}

		pair.second.give_peel(letters);
	}

	return false;
}

void Game::try_to_start()
{
	// if already started
	if (playing)
		return;

	// if not enough players
	if (players.size() < 2)
		return;

	// if players aren't ready
	for (const auto& pair : players)
		if (!pair.second.ready)
			return;

	ready_to_peel = true;
}

void Game::check_waiting()
{
	for (const auto& pair : players)
		if (pair.second.has_pending())
			return;

	waiting = false;
}
<|endoftext|>


<commit_before>#ifdef ENABLE_MPI

#include <stddef.h>
#include <sstream>

#include "Tools/Exception/exception.hpp"

#include "Monitor_BFER_reduction_mpi.hpp"

using namespace aff3ct;
using namespace aff3ct::module;

struct monitor_vals
{
	unsigned long long n_be;
	unsigned long long n_fe;
	unsigned long long n_fra;
	float              MI_sum;
};

void MPI_SUM_monitor_vals_func(void *in, void *inout, int *len, MPI_Datatype *datatype)
{
	auto    in_cvt = static_cast<monitor_vals*>(in   );
	auto inout_cvt = static_cast<monitor_vals*>(inout);

	for (auto i = 0; i < *len; i++)
	{
		inout_cvt[i].n_be  += in_cvt[i].n_be;
		inout_cvt[i].n_fe  += in_cvt[i].n_fe;

		inout_cvt[i].n_fra += in_cvt[i].n_fra;
		inout_cvt[i].MI_sum+= inout_cvt[i].MI_sum;
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::Monitor_BFER_reduction_mpi(const std::vector<Monitor_BFER<B,R>*> &monitors,
                             const std::thread::id master_thread_id,
                             const std::chrono::nanoseconds d_mpi_comm_frequency)
: Monitor_BFER_reduction<B,R>(monitors),
  master_thread_id(master_thread_id),
  is_fe_limit_achieved(false),
  t_last_mpi_comm(std::chrono::steady_clock::now()),
  d_mpi_comm_frequency(d_mpi_comm_frequency)
{
	const std::string name = "Monitor_BFER_reduction_mpi";
	this->set_name(name);

	int blen[4];
	MPI_Aint displacements[4];
	MPI_Datatype oldtypes[4];

	blen[0] = 1; displacements[0] = offsetof(monitor_vals, n_be  ); oldtypes[0] = MPI_UNSIGNED_LONG_LONG;
	blen[1] = 1; displacements[1] = offsetof(monitor_vals, n_fe  ); oldtypes[1] = MPI_UNSIGNED_LONG_LONG;
	blen[2] = 1; displacements[2] = offsetof(monitor_vals, n_fra ); oldtypes[2] = MPI_UNSIGNED_LONG_LONG;
	blen[3] = 1; displacements[3] = offsetof(monitor_vals, MI_sum); oldtypes[3] = MPI_FLOAT;

	if (auto ret = MPI_Type_create_struct(4, blen, displacements, oldtypes, &MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_create_struct' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Type_commit(&MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_commit' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Op_create(MPI_SUM_monitor_vals_func, true, &MPI_SUM_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Op_create' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::~Monitor_BFER_reduction_mpi()
{
}

template <typename B, typename R>
bool Monitor_BFER_reduction_mpi<B,R>
::fe_limit_achieved()
{
	// only the master thread can do this
	if (std::this_thread::get_id() == this->master_thread_id &&
	    ((std::chrono::steady_clock::now() - t_last_mpi_comm) >= d_mpi_comm_frequency))
	{
		monitor_vals mvals_recv;
		monitor_vals mvals_send = { this->get_n_be()           - this->n_bit_errors,
		                            this->get_n_fe()           - this->n_frame_errors,
		                            this->get_n_analyzed_fra() - this->n_analyzed_frames,
		                            this->get_MI_sum()         - this->MI_sum };

		MPI_Allreduce(&mvals_send, &mvals_recv, 1, MPI_monitor_vals, MPI_SUM_monitor_vals, MPI_COMM_WORLD);

		this->n_bit_errors      = mvals_recv.n_be   - mvals_send.n_be;
		this->n_frame_errors    = mvals_recv.n_fe   - mvals_send.n_fe;
		this->n_analyzed_frames = mvals_recv.n_fra  - mvals_send.n_fra;
		this->MI_sum            = mvals_recv.MI_sum - mvals_send.MI_sum;

		t_last_mpi_comm = std::chrono::steady_clock::now();

		is_fe_limit_achieved = mvals_recv.n_fe >= this->get_fe_limit();
	}

	return is_fe_limit_achieved;
}

template <typename B, typename R>
void Monitor_BFER_reduction_mpi<B,R>
::reset()
{
	Monitor_BFER_reduction<B,R>::reset();
	is_fe_limit_achieved = false;
}

// ==================================================================================== explicit template instantiation
#include "Tools/types.h"
#ifdef MULTI_PREC
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_8, Q_8>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_16,Q_16>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_32,Q_32>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_64,Q_64>;
#else
template class aff3ct::module::Monitor_BFER_reduction_mpi<B,Q>;
#endif
// ==================================================================================== explicit template instantiation

#endif
<commit_msg>Fix MPI compilation<commit_after>#ifdef ENABLE_MPI

#include <stddef.h>
#include <sstream>

#include "Tools/Exception/exception.hpp"

#include "Monitor_BFER_reduction_mpi.hpp"

using namespace aff3ct;
using namespace aff3ct::module;

struct monitor_vals
{
	unsigned long long n_be;
	unsigned long long n_fe;
	unsigned long long n_fra;
	float              MI_sum;
};

void MPI_SUM_monitor_vals_func(void *in, void *inout, int *len, MPI_Datatype *datatype)
{
	auto    in_cvt = static_cast<monitor_vals*>(in   );
	auto inout_cvt = static_cast<monitor_vals*>(inout);

	for (auto i = 0; i < *len; i++)
	{
		inout_cvt[i].n_be  += in_cvt[i].n_be;
		inout_cvt[i].n_fe  += in_cvt[i].n_fe;

		inout_cvt[i].n_fra += in_cvt[i].n_fra;
		inout_cvt[i].MI_sum+= inout_cvt[i].MI_sum;
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::Monitor_BFER_reduction_mpi(const std::vector<Monitor_BFER<B,R>*> &monitors,
                             const std::thread::id master_thread_id,
                             const std::chrono::nanoseconds d_mpi_comm_frequency)
: Monitor_BFER_reduction<B,R>(monitors),
  master_thread_id(master_thread_id),
  is_fe_limit_achieved(false),
  t_last_mpi_comm(std::chrono::steady_clock::now()),
  d_mpi_comm_frequency(d_mpi_comm_frequency)
{
	const std::string name = "Monitor_BFER_reduction_mpi";
	this->set_name(name);

	int blen[4];
	MPI_Aint displacements[4];
	MPI_Datatype oldtypes[4];

	blen[0] = 1; displacements[0] = offsetof(monitor_vals, n_be  ); oldtypes[0] = MPI_UNSIGNED_LONG_LONG;
	blen[1] = 1; displacements[1] = offsetof(monitor_vals, n_fe  ); oldtypes[1] = MPI_UNSIGNED_LONG_LONG;
	blen[2] = 1; displacements[2] = offsetof(monitor_vals, n_fra ); oldtypes[2] = MPI_UNSIGNED_LONG_LONG;
	blen[3] = 1; displacements[3] = offsetof(monitor_vals, MI_sum); oldtypes[3] = MPI_FLOAT;

	if (auto ret = MPI_Type_create_struct(4, blen, displacements, oldtypes, &MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_create_struct' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Type_commit(&MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_commit' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Op_create(MPI_SUM_monitor_vals_func, true, &MPI_SUM_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Op_create' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::~Monitor_BFER_reduction_mpi()
{
}

template <typename B, typename R>
bool Monitor_BFER_reduction_mpi<B,R>
::fe_limit_achieved()
{
	// only the master thread can do this
	if (std::this_thread::get_id() == this->master_thread_id &&
	    ((std::chrono::steady_clock::now() - t_last_mpi_comm) >= d_mpi_comm_frequency))
	{
		monitor_vals mvals_recv;
		monitor_vals mvals_send = { this->get_n_be()           - this->n_bit_errors,
		                            this->get_n_fe()           - this->n_frame_errors,
		                            this->get_n_analyzed_fra() - this->n_analyzed_frames,
		                            this->get_MI_sum()         - this->MI_sum };

		MPI_Allreduce(&mvals_send, &mvals_recv, 1, MPI_monitor_vals, MPI_SUM_monitor_vals, MPI_COMM_WORLD);

		this->n_bit_errors      = mvals_recv.n_be   - mvals_send.n_be;
		this->n_frame_errors    = mvals_recv.n_fe   - mvals_send.n_fe;
		this->n_analyzed_frames = mvals_recv.n_fra  - mvals_send.n_fra;
		this->MI_sum            = mvals_recv.MI_sum - mvals_send.MI_sum;

		t_last_mpi_comm = std::chrono::steady_clock::now();

		is_fe_limit_achieved = mvals_recv.n_fe >= this->get_fe_limit();
	}

	return is_fe_limit_achieved;
}

template <typename B, typename R>
void Monitor_BFER_reduction_mpi<B,R>
::reset()
{
	Monitor_BFER_reduction<B,R>::reset();
	is_fe_limit_achieved = false;
}

// ==================================================================================== explicit template instantiation
#include "Tools/types.h"
#ifdef MULTI_PREC
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_8, R_8>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_16,R_16>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_32,R_32>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_64,R_64>;
#else
template class aff3ct::module::Monitor_BFER_reduction_mpi<B,R>;
#endif
// ==================================================================================== explicit template instantiation

#endif
<|endoftext|>


<commit_before>#include "inputdevice.h"
#include "ui_inputdevice.h"

#include <QAudioInput> // not final
#include <QDebug> // not final
#include <QMessageBox>

namespace {
template <class IndexMapType, class ItemType, class Callable>
static void insertWithDefault(QComboBox* comboBox, IndexMapType& map,
                              QList<ItemType> items, ItemType defaultItem,
                              Callable stringGenerator)
{
  int itemPosition = 0;

  comboBox->clear();
  map.clear();

  {
    map[itemPosition] = defaultItem;

    comboBox->insertItem(itemPosition++,
                         "Default: " + stringGenerator(defaultItem));
  }

  comboBox->insertSeparator(itemPosition++);

  for (auto item : items) {
    map[itemPosition] = item;

    comboBox->insertItem(itemPosition++, stringGenerator(item));
  }
}

bool validateAudioDevice(QString& errorMessage,
                         QAudioDeviceInfo& audioDeviceInfo)
{
#define CONDITION(cond) [](QAudioDeviceInfo& adi) { return cond; }

  struct {
    std::function<bool(QAudioDeviceInfo& adi)> test;
    const char* failureMessage;
  } tests[] = {

        {CONDITION(adi.supportedByteOrders().contains(
             static_cast<QAudioFormat::Endian>(QSysInfo::ByteOrder))),
         "Audio device does not support system byte order."},

        {CONDITION(adi.supportedChannelCounts().contains(1)),
         "Audio device does not support mono input."},

        {CONDITION(adi.supportedCodecs().contains("audio/pcm")),
         "Audio device does not support PCM codec."},

        {CONDITION(
             adi.supportedSampleTypes().contains(QAudioFormat::UnSignedInt)),
         "Audio device does not support unsigned int."},

	/*
        {CONDITION(false), "Failure test."},
        {CONDITION(false), "Failure test 2."},
	*/

    };

#undef CONDITION

  bool good = true;
  for (auto t : tests) {
    if (!t.test(audioDeviceInfo)) {
      if (!good) { errorMessage.append("\n"); }
      errorMessage.append(t.failureMessage);
      good = false;
    }
  }

  return good;
}

} // namespace anonymous

InputDevice::InputDevice(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::InputDevice)
{
  ui->setupUi(this);

  insertWithDefault(ui->cmbDevice, m_indexToDevice,
                    QAudioDeviceInfo::availableDevices(QAudio::AudioInput),
                    QAudioDeviceInfo::defaultInputDevice(),
                    [](QAudioDeviceInfo& audioDeviceInfo) {
    return audioDeviceInfo.deviceName();
  });

}

InputDevice::~InputDevice()
{
    delete ui;
}

void InputDevice::on_cmbDevice_currentIndexChanged(int index)
{
  if (index == -1) return; // If combo box gets cleared

  auto device = m_indexToDevice[index];
  auto preferredAudioFormat = device.preferredFormat();

  insertWithDefault(ui->cmbSampleRate, m_indexToSampleRate,
                    device.supportedSampleRates(),
                    preferredAudioFormat.sampleRate(), [](int sampleRate) {
                      return QString::number(sampleRate);
                    });

  insertWithDefault(ui->cmbSampleSize, m_indexToSampleSize,
                    device.supportedSampleSizes(),
                    preferredAudioFormat.sampleSize(), [](int sampleSize) {
                      return QString::number(sampleSize);
                    });

  QString errorMessage;
  if (!validateAudioDevice(errorMessage, device)) {
    // TODO: Put this on message queue, since it won't make much sense
    // if this is shown before the config popup.
    QMessageBox::critical(this, tr("Unsupported input device"), errorMessage);
  }
}
<commit_msg>static const struct<commit_after>#include "inputdevice.h"
#include "ui_inputdevice.h"

#include <QAudioInput> // not final
#include <QDebug> // not final
#include <QMessageBox>

namespace {
template <class IndexMapType, class ItemType, class Callable>
static void insertWithDefault(QComboBox* comboBox, IndexMapType& map,
                              QList<ItemType> items, ItemType defaultItem,
                              Callable stringGenerator)
{
  int itemPosition = 0;

  comboBox->clear();
  map.clear();

  {
    map[itemPosition] = defaultItem;

    comboBox->insertItem(itemPosition++,
                         "Default: " + stringGenerator(defaultItem));
  }

  comboBox->insertSeparator(itemPosition++);

  for (auto item : items) {
    map[itemPosition] = item;

    comboBox->insertItem(itemPosition++, stringGenerator(item));
  }
}

bool validateAudioDevice(QString& errorMessage,
                         QAudioDeviceInfo& audioDeviceInfo)
{
#define CONDITION(cond) [](QAudioDeviceInfo& adi) { return cond; }

  static const struct {
    std::function<bool(QAudioDeviceInfo& adi)> test;
    const char* failureMessage;
  } tests[] = {

        {CONDITION(adi.supportedByteOrders().contains(
             static_cast<QAudioFormat::Endian>(QSysInfo::ByteOrder))),
         "Audio device does not support system byte order."},

        {CONDITION(adi.supportedChannelCounts().contains(1)),
         "Audio device does not support mono input."},

        {CONDITION(adi.supportedCodecs().contains("audio/pcm")),
         "Audio device does not support PCM codec."},

        {CONDITION(
             adi.supportedSampleTypes().contains(QAudioFormat::UnSignedInt)),
         "Audio device does not support unsigned int."},

	/*
        {CONDITION(false), "Failure test."},
        {CONDITION(false), "Failure test 2."},
	*/

    };

#undef CONDITION

  bool good = true;
  for (auto t : tests) {
    if (!t.test(audioDeviceInfo)) {
      if (!good) { errorMessage.append("\n"); }
      errorMessage.append(t.failureMessage);
      good = false;
    }
  }

  return good;
}

} // namespace anonymous

InputDevice::InputDevice(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::InputDevice)
{
  ui->setupUi(this);

  insertWithDefault(ui->cmbDevice, m_indexToDevice,
                    QAudioDeviceInfo::availableDevices(QAudio::AudioInput),
                    QAudioDeviceInfo::defaultInputDevice(),
                    [](QAudioDeviceInfo& audioDeviceInfo) {
    return audioDeviceInfo.deviceName();
  });

}

InputDevice::~InputDevice()
{
    delete ui;
}

void InputDevice::on_cmbDevice_currentIndexChanged(int index)
{
  if (index == -1) return; // If combo box gets cleared

  auto device = m_indexToDevice[index];
  auto preferredAudioFormat = device.preferredFormat();

  insertWithDefault(ui->cmbSampleRate, m_indexToSampleRate,
                    device.supportedSampleRates(),
                    preferredAudioFormat.sampleRate(), [](int sampleRate) {
                      return QString::number(sampleRate);
                    });

  insertWithDefault(ui->cmbSampleSize, m_indexToSampleSize,
                    device.supportedSampleSizes(),
                    preferredAudioFormat.sampleSize(), [](int sampleSize) {
                      return QString::number(sampleSize);
                    });

  QString errorMessage;
  if (!validateAudioDevice(errorMessage, device)) {
    // TODO: Put this on message queue, since it won't make much sense
    // if this is shown before the config popup.
    QMessageBox::critical(this, tr("Unsupported input device"), errorMessage);
  }
}
<|endoftext|>


<commit_before>#include <Python.h>
#include <stdexcept>

#include "neuron.hpp"
#include "network.hpp"

int glob_argc;
char **glob_argv;

static PyObject* test(PyObject* self)
{
    //Network* network = new Network(14, 4, 2);
    //network->nonsensory_neurons[0]->calculate_potential();

    Py_RETURN_NONE;
}

static PyObject* hello_world(PyObject* self)
{
    std::cout << "Hello World!" << std::endl;

    Py_RETURN_NONE;
}

void parse_iterable(std::vector<double> &arr, PyObject *iter)
{
    while (true) {
        PyObject *next = PyIter_Next(iter);
        if (!next) {
            // nothing left in the iterator
            break;
        }

        if (!PyFloat_Check(next)) {
            throw std::invalid_argument("One of the arguments contains an illegal value (other than float)");
        }

        double val = PyFloat_AsDouble(next);
        arr.push_back(val);
    }
}

typedef struct {
    PyObject_HEAD
    Network * ptrObj;
} PyNetwork;

static int PyNetwork_init(PyNetwork *self, PyObject *args, PyObject *kwargs)
// initialize PyNetwork Object
{
    int size;
    int input_dim = 0;
    int output_dim = 0;
    double connectivity = 0.01;
    int precision = 2;
    int randomly_fire = false;
    int dynamic_output = false;
    int visualization = false;
    double decay_factor =  1.0;

    static char *kwlist[] = {"size", "input_dim", "output_dim", "connectivity", "precision", "randomly_fire", "dynamic_output", "visualization", "decay_factor", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwargs, "i|iidipppd", kwlist, &size, &input_dim, &output_dim, &connectivity, &precision, &randomly_fire, &dynamic_output, &visualization, &decay_factor))
        return -1;

    self->ptrObj = new Network(size, input_dim, output_dim, connectivity, precision, randomly_fire, dynamic_output, visualization, decay_factor);

    return 0;
}

static void PyNetwork_dealloc(PyNetwork * self)
// destruct the object
{
    delete self->ptrObj;
    Py_TYPE(self)->tp_free(self);
}

static PyObject * PyNetwork_load(PyNetwork* self, PyObject* args, PyObject *kwargs)
{
    std::vector<double> input_arr;
    std::vector<double> output_arr;
    PyObject *input_obj;
    PyObject *output_obj;

    if (! PyArg_ParseTuple(args, "OO", &input_obj, &output_obj))
        throw std::invalid_argument("Wrong type of argument");

    PyObject *input_iter = PyObject_GetIter(input_obj);
    PyObject *output_iter = PyObject_GetIter(output_obj);
    if (!input_iter || !output_iter) {
        throw std::invalid_argument("One of the arguments is not iterable");
    }

    parse_iterable(input_arr, input_iter);
    parse_iterable(output_arr, output_iter);

    (self->ptrObj)->load(input_arr, output_arr);
    return Py_BuildValue("");
}

static PyMethodDef PyNetwork_methods[] = {
    {"load", (PyCFunction)PyNetwork_load, METH_VARARGS, "Load input and ouput the neural network" },
    {NULL}  /* Sentinel */
};

static PyTypeObject PyNetworkType = { PyVarObject_HEAD_INIT(NULL, 0)
    "plexus.Network"   /* tp_name */
};

static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "cplexus",          /* name of module */
    "",                 /* module documentation, may be NULL */
    -1,                 /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    NULL, NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC PyInit_cplexus(void)
// create the module
{
    PyObject* m;

    PyNetworkType.tp_new = PyType_GenericNew;
    PyNetworkType.tp_basicsize=sizeof(PyNetwork);
    PyNetworkType.tp_dealloc=(destructor) PyNetwork_dealloc;
    PyNetworkType.tp_flags=Py_TPFLAGS_DEFAULT;
    PyNetworkType.tp_doc="Network objects";
    PyNetworkType.tp_methods=PyNetwork_methods;
    //~ PyNetworkType.tp_members=Noddy_members;
    PyNetworkType.tp_init=(initproc)PyNetwork_init;

    if (PyType_Ready(&PyNetworkType) < 0)
        return NULL;

    m = PyModule_Create(&moduledef);
    if (m == NULL)
        return NULL;

    Py_INCREF(&PyNetworkType);
    PyModule_AddObject(m, "Network", (PyObject *)&PyNetworkType); // Add Network object to the module
    return m;
}

void initcplexus(void)
{
    PyInit_cplexus();
}

int main(int argc, char *argv[])
{
    glob_argc = argc;
    glob_argv = argv;

    wchar_t *program = Py_DecodeLocale(argv[0], NULL);

    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramName(program);

    /* Initialize the Python interpreter.  Required. */
    Py_Initialize();

    /* Add a static module */
    initcplexus();
}
<commit_msg>Fix the C++ Python wrapper of Network::load() function<commit_after>#include <Python.h>
#include <stdexcept>

#include "neuron.hpp"
#include "network.hpp"

int glob_argc;
char **glob_argv;

static PyObject* test(PyObject* self)
{
    //Network* network = new Network(14, 4, 2);
    //network->nonsensory_neurons[0]->calculate_potential();

    Py_RETURN_NONE;
}

static PyObject* hello_world(PyObject* self)
{
    std::cout << "Hello World!" << std::endl;

    Py_RETURN_NONE;
}

void parse_iterable(std::vector<double> &arr, PyObject *iter)
{
    while (true) {
        PyObject *next = PyIter_Next(iter);
        if (!next) {
            // nothing left in the iterator
            break;
        }

        if (!PyFloat_Check(next)) {
            throw std::invalid_argument("One of the arguments contains an illegal value (other than float)");
        }

        double val = PyFloat_AsDouble(next);
        arr.push_back(val);
    }
}

typedef struct {
    PyObject_HEAD
    Network * ptrObj;
} PyNetwork;

static int PyNetwork_init(PyNetwork *self, PyObject *args, PyObject *kwargs)
// initialize PyNetwork Object
{
    int size;
    int input_dim = 0;
    int output_dim = 0;
    double connectivity = 0.01;
    int precision = 2;
    int randomly_fire = false;
    int dynamic_output = false;
    int visualization = false;
    double decay_factor =  1.0;

    static char *kwlist[] = {"size", "input_dim", "output_dim", "connectivity", "precision", "randomly_fire", "dynamic_output", "visualization", "decay_factor", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwargs, "i|iidipppd", kwlist, &size, &input_dim, &output_dim, &connectivity, &precision, &randomly_fire, &dynamic_output, &visualization, &decay_factor))
        return -1;

    self->ptrObj = new Network(size, input_dim, output_dim, connectivity, precision, randomly_fire, dynamic_output, visualization, decay_factor);

    return 0;
}

static void PyNetwork_dealloc(PyNetwork * self)
// destruct the object
{
    delete self->ptrObj;
    Py_TYPE(self)->tp_free(self);
}

static PyObject * PyNetwork_load(PyNetwork* self, PyObject* args, PyObject *kwargs)
{
    std::vector<double> input_arr;
    std::vector<double> output_arr;
    PyObject *input_obj;
    PyObject *output_obj = Py_None;

    static char *kwlist[] = {"input_obj", "output_obj", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &input_obj, &output_obj))
        throw std::invalid_argument("Wrong type of argument");

    PyObject *input_iter = PyObject_GetIter(input_obj);
    if (!input_iter) {
        throw std::invalid_argument("Input argument is not iterable");
    }
    parse_iterable(input_arr, input_iter);

    if (output_obj != Py_None) {
        PyObject *output_iter = PyObject_GetIter(output_obj);
        if (!output_iter) {
            throw std::invalid_argument("Output argument is not iterable");
        }
        parse_iterable(output_arr, output_iter);
    }

    (self->ptrObj)->load(input_arr, output_arr);

    return Py_BuildValue("");
}

static PyMethodDef PyNetwork_methods[] = {
    {"load", (PyCFunction)PyNetwork_load, METH_VARARGS | METH_KEYWORDS, "Load input and output the neural network" },
    {NULL}  /* Sentinel */
};

static PyTypeObject PyNetworkType = { PyVarObject_HEAD_INIT(NULL, 0)
    "plexus.Network"   /* tp_name */
};

static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "cplexus",          /* name of module */
    "",                 /* module documentation, may be NULL */
    -1,                 /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    NULL, NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC PyInit_cplexus(void)
// create the module
{
    PyObject* m;

    PyNetworkType.tp_new = PyType_GenericNew;
    PyNetworkType.tp_basicsize=sizeof(PyNetwork);
    PyNetworkType.tp_dealloc=(destructor) PyNetwork_dealloc;
    PyNetworkType.tp_flags=Py_TPFLAGS_DEFAULT;
    PyNetworkType.tp_doc="Network objects";
    PyNetworkType.tp_methods=PyNetwork_methods;
    //~ PyNetworkType.tp_members=Noddy_members;
    PyNetworkType.tp_init=(initproc)PyNetwork_init;

    if (PyType_Ready(&PyNetworkType) < 0)
        return NULL;

    m = PyModule_Create(&moduledef);
    if (m == NULL)
        return NULL;

    Py_INCREF(&PyNetworkType);
    PyModule_AddObject(m, "Network", (PyObject *)&PyNetworkType); // Add Network object to the module
    return m;
}

void initcplexus(void)
{
    PyInit_cplexus();
}

int main(int argc, char *argv[])
{
    glob_argc = argc;
    glob_argv = argv;

    wchar_t *program = Py_DecodeLocale(argv[0], NULL);

    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramName(program);

    /* Initialize the Python interpreter.  Required. */
    Py_Initialize();

    /* Add a static module */
    initcplexus();
}
<|endoftext|>


<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "memcached/memcached_btree/get_cas.hpp"

#include "errors.hpp"
#include <boost/bind.hpp>

#include "arch/runtime/coroutines.hpp"
#include "buffer_cache/alt/alt.hpp"
#include "concurrency/promise.hpp"
#include "memcached/memcached_btree/btree_data_provider.hpp"
#include "memcached/memcached_btree/modify_oper.hpp"

// This function is like get(), except that it sets a CAS value if
// there isn't one already, so it has to be a
// memcached_modify_oper_t. Potentially we can use a regular get() for
// this (that replaces itself with this one if a CAS value hasn't been
// set, for instance), but depending on how CAS is used, that may be
// unnecessary.

struct memcached_get_cas_oper_t : public memcached_modify_oper_t, public home_thread_mixin_debug_only_t {
    memcached_get_cas_oper_t(cas_t _proposed_cas, promise_t<get_result_t> *_res)
        : proposed_cas(_proposed_cas), res(_res) { }

    bool operate(buf_parent_t leaf,
                 scoped_malloc_t<memcached_value_t> *value) {
        if (!value->has()) {
            // If not found, there's nothing to do.
            res->pulse(get_result_t());
            return false;
        }

        bool there_was_cas_before = (*value)->has_cas();
        cas_t cas_to_report;
        if (there_was_cas_before) {
            // How convenient, there already was a CAS.
            cas_to_report = (*value)->cas();
        } else {
            // This doesn't set the CAS -- it just makes room for the
            // CAS, and run_memcached_modify_oper() sets the CAS.
            (*value)->add_cas(leaf.cache()->get_block_size());
            cas_to_report = proposed_cas;
        }

        // Deliver the value to the client via the promise_t we got.
        counted_t<data_buffer_t> dp = value_to_data_buffer(value->get(), leaf);
        res->pulse(get_result_t(dp, (*value)->mcflags(), cas_to_report));

        // Return whether we made a change to the value.
        return !there_was_cas_before;
    }

    int compute_expected_change_count(UNUSED block_size_t block_size) {
        return 1;
    }

    cas_t proposed_cas;
    get_result_t result;
    promise_t<get_result_t> *res;
};

void co_memcached_get_cas(const store_key_t &key, cas_t proposed_cas,
                          exptime_t effective_time, repli_timestamp_t timestamp,
                          btree_slice_t *slice, promise_t<get_result_t> *res,
                          superblock_t *superblock) {

    memcached_get_cas_oper_t oper(proposed_cas, res);
    run_memcached_modify_oper(&oper, slice, key, proposed_cas, effective_time, timestamp, superblock);
}

get_result_t memcached_get_cas(const store_key_t &key, btree_slice_t *slice,
                               cas_t proposed_cas, exptime_t effective_time,
                               repli_timestamp_t timestamp,
                               superblock_t *superblock) {
    promise_t<get_result_t> res;
    // RSI: std::bind.
    coro_t::spawn_now_dangerously(boost::bind(co_memcached_get_cas, boost::ref(key),
                                              proposed_cas, effective_time,
                                              timestamp, slice, &res,
                                              boost::ref(superblock)));
    return res.wait();
}

<commit_msg>Fixed a petty RSI about boost::bind.<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "memcached/memcached_btree/get_cas.hpp"

#include "arch/runtime/coroutines.hpp"
#include "buffer_cache/alt/alt.hpp"
#include "concurrency/promise.hpp"
#include "memcached/memcached_btree/btree_data_provider.hpp"
#include "memcached/memcached_btree/modify_oper.hpp"

// This function is like get(), except that it sets a CAS value if
// there isn't one already, so it has to be a
// memcached_modify_oper_t. Potentially we can use a regular get() for
// this (that replaces itself with this one if a CAS value hasn't been
// set, for instance), but depending on how CAS is used, that may be
// unnecessary.

struct memcached_get_cas_oper_t : public memcached_modify_oper_t, public home_thread_mixin_debug_only_t {
    memcached_get_cas_oper_t(cas_t _proposed_cas, promise_t<get_result_t> *_res)
        : proposed_cas(_proposed_cas), res(_res) { }

    bool operate(buf_parent_t leaf,
                 scoped_malloc_t<memcached_value_t> *value) {
        if (!value->has()) {
            // If not found, there's nothing to do.
            res->pulse(get_result_t());
            return false;
        }

        bool there_was_cas_before = (*value)->has_cas();
        cas_t cas_to_report;
        if (there_was_cas_before) {
            // How convenient, there already was a CAS.
            cas_to_report = (*value)->cas();
        } else {
            // This doesn't set the CAS -- it just makes room for the
            // CAS, and run_memcached_modify_oper() sets the CAS.
            (*value)->add_cas(leaf.cache()->get_block_size());
            cas_to_report = proposed_cas;
        }

        // Deliver the value to the client via the promise_t we got.
        counted_t<data_buffer_t> dp = value_to_data_buffer(value->get(), leaf);
        res->pulse(get_result_t(dp, (*value)->mcflags(), cas_to_report));

        // Return whether we made a change to the value.
        return !there_was_cas_before;
    }

    int compute_expected_change_count(UNUSED block_size_t block_size) {
        return 1;
    }

    cas_t proposed_cas;
    get_result_t result;
    promise_t<get_result_t> *res;
};

void co_memcached_get_cas(const store_key_t &key, cas_t proposed_cas,
                          exptime_t effective_time, repli_timestamp_t timestamp,
                          btree_slice_t *slice, promise_t<get_result_t> *res,
                          superblock_t *superblock) {

    memcached_get_cas_oper_t oper(proposed_cas, res);
    run_memcached_modify_oper(&oper, slice, key, proposed_cas, effective_time, timestamp, superblock);
}

get_result_t memcached_get_cas(const store_key_t &key, btree_slice_t *slice,
                               cas_t proposed_cas, exptime_t effective_time,
                               repli_timestamp_t timestamp,
                               superblock_t *superblock) {
    promise_t<get_result_t> res;
    coro_t::spawn_now_dangerously(std::bind(co_memcached_get_cas, std::ref(key),
                                            proposed_cas, effective_time,
                                            timestamp, slice, &res,
                                            std::ref(superblock)));
    return res.wait();
}

<|endoftext|>


<commit_before>#include "Geometry.h"

#include <cstdio>
#include <fstream>
#include <stdexcept>

#include "spruce.hh"

using std::string;
using std::ostream;
using std::istringstream;
using std::ifstream;

using Eigen::Vector3i;
using Eigen::Vector3d;
using Eigen::RowVectorXd;
using Eigen::Matrix3Xd;
using Eigen::Matrix3Xi;

namespace DrakeShapes {
const int Geometry::NUM_BBOX_POINTS = 8;
const int Sphere::NUM_POINTS = 1;
const int Capsule::NUM_POINTS = 2;

string ShapeToString(Shape ss) {
  switch (ss) {
    case UNKNOWN:
      return "UNKNOWN";
    case BOX:
      return "BOX";
    case SPHERE:
      return "SPHERE";
    case CYLINDER:
      return "CYLINDER";
    case MESH:
      return "MESH";
    case MESH_POINTS:
      return "MESH_POINTS";
    case CAPSULE:
      return "CAPSULE";
  }
  return "UNDEFINED";
}

Geometry::Geometry() : shape(UNKNOWN) {}

Geometry::Geometry(const Geometry &other) { shape = other.getShape(); }

Geometry::Geometry(Shape shape) : shape(shape) {}

Shape Geometry::getShape() const { return shape; }

Geometry *Geometry::clone() const { return new Geometry(*this); }

void Geometry::getPoints(Matrix3Xd &points) const { points = Matrix3Xd(); }

void Geometry::getBoundingBoxPoints(Matrix3Xd &points) const {
  points = Matrix3Xd();
}

void Geometry::getBoundingBoxPoints(double x_half_width, double y_half_width,
                                    double z_half_width,
                                    Eigen::Matrix3Xd &points) const {
  // Return axis-aligned bounding-box vertices
  points.resize(3, NUM_BBOX_POINTS);

  RowVectorXd cx(NUM_BBOX_POINTS), cy(NUM_BBOX_POINTS), cz(NUM_BBOX_POINTS);
  cx << -1, 1, 1, -1, -1, 1, 1, -1;
  cy << 1, 1, 1, 1, -1, -1, -1, -1;
  cz << 1, 1, -1, -1, -1, -1, 1, 1;
  cx = cx * x_half_width;
  cy = cy * y_half_width;
  cz = cz * z_half_width;

  points << cx, cy, cz;
}

ostream &operator<<(ostream &out, const Geometry &gg) {
  out << ShapeToString(gg.getShape()) << ", " << gg.NUM_BBOX_POINTS;
  return out;
}

Sphere::Sphere(double radius) : Geometry(SPHERE), radius(radius) {}

Sphere *Sphere::clone() const { return new Sphere(*this); }

void Sphere::getPoints(Matrix3Xd &points) const {
  points = Matrix3Xd::Zero(3, NUM_POINTS);
}

void Sphere::getBoundingBoxPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(radius, radius, radius, points);
}

void Sphere::getTerrainContactPoints(Matrix3Xd &points) const {
  if (radius < 1e-6)
    getPoints(points);
  else
    points = Matrix3Xd();
}

ostream &operator<<(ostream &out, const Sphere &ss) {
  out << static_cast<const Geometry &>(ss) << ", " << ss.radius << ", "
      << ss.NUM_POINTS;
  return out;
}

Box::Box(const Eigen::Vector3d &size) : Geometry(BOX), size(size) {}

Box *Box::clone() const { return new Box(*this); }

void Box::getPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(size(0) / 2.0, size(1) / 2.0, size(2) / 2.0,
                                 points);
}

void Box::getBoundingBoxPoints(Matrix3Xd &points) const { getPoints(points); }

void Box::getTerrainContactPoints(Matrix3Xd &points) const {
  getPoints(points);
}

ostream &operator<<(ostream &out, const Box &bb) {
  out << static_cast<const Geometry &>(bb) << ", " << bb.size.transpose();
  return out;
}

Cylinder::Cylinder(double radius, double length)
    : Geometry(CYLINDER), radius(radius), length(length) {}

Cylinder *Cylinder::clone() const { return new Cylinder(*this); }

void Cylinder::getPoints(Matrix3Xd &points) const {
  static bool warnOnce = true;
  if (warnOnce) {
    std::cerr << "Warning: DrakeShapes::Cylinder::getPoints(): "
        "This method returns the vertices of the cylinder''s bounding-box."
         << std::endl;
    warnOnce = false;
  }

  getBoundingBoxPoints(points);
}

void Cylinder::getBoundingBoxPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(radius, radius, length / 2.0, points);
}

ostream &operator<<(ostream &out, const Cylinder &cc) {
  out << static_cast<const Geometry &>(cc) << ", " << cc.radius << ", "
      << cc.length;
  return out;
}

Capsule::Capsule(double radius, double length)
    : Geometry(CAPSULE), radius(radius), length(length) {}

Capsule *Capsule::clone() const { return new Capsule(*this); }

void Capsule::getPoints(Matrix3Xd &points) const {
  // Return segment end-points
  points.resize(Eigen::NoChange, NUM_POINTS);
  RowVectorXd cx = RowVectorXd::Zero(NUM_POINTS);
  RowVectorXd cy = RowVectorXd::Zero(NUM_POINTS);
  RowVectorXd cz = RowVectorXd::Zero(NUM_POINTS);
  cz << length / 2.0, -length / 2.0;

  points << cx, cy, cz;
}

void Capsule::getBoundingBoxPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(radius, radius, (length / 2.0 + radius),
                                 points);
}

ostream &operator<<(ostream &out, const Capsule &cc) {
  out << static_cast<const Geometry &>(cc) << ", " << cc.radius << ", "
      << cc.length;
  return out;
}

Mesh::Mesh(const string &filename)
    : Geometry(MESH), scale(1.0, 1.0, 1.0), filename(filename) {}

Mesh::Mesh(const string &filename, const string &resolved_filename)
    : Geometry(MESH),
      scale(1.0, 1.0, 1.0),
      filename(filename),
      resolved_filename(resolved_filename) {}

bool Mesh::extractMeshVertices(Matrix3Xd& vertex_coordinates) const {
  if (resolved_filename.empty()) return false;

  string obj_file_name = FindFileWithObjExtension();
  ifstream file(obj_file_name);
  if (!file) {
    throw std::runtime_error(
        "Error opening file \"" + obj_file_name + "\".");
  }

  string line;
  // Count the number of vertices and resize vertex_coordinates.
  int num_vertices = 0;
  while (getline(file, line)) {
    istringstream iss(line);
    string type;
    if (iss >> type && type == "v") {
      ++num_vertices;
    }
  }
  vertex_coordinates.resize(3, num_vertices);

  file.clear();
  file.seekg(0, file.beg);

  double d;
  int j = 0;
  while (getline(file, line)) {
    istringstream iss(line);
    string type;
    if (iss >> type && type == "v") {
      int i = 0;
      while (iss >> d) {
        vertex_coordinates(i++, j) = d;
      }
      ++j;
    }
  }
  return true;
}

string Mesh::FindFileWithObjExtension() const {
  spruce::path spath(resolved_filename);
  string ext = spath.extension();
  std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);

  if (ext.compare(".obj") == 0) {
    // Checks if the file with the obj extension exists.
    if (!spath.exists()) {
      throw std::runtime_error(
          "Unable to open file \"" + spath.getStr() + "\".");
    }
  } else {
    // Tries changing the extension to obj.
    spath.setExtension(".obj");
    if (!spath.exists()) {
      throw std::runtime_error(
          "Unable to resolve an obj file from the filename \""
              + spath.getStr() + "\" provided.");
    }
  }

  return spath.getStr();
}

void Mesh::LoadObjFile(PointsVector* vertices,
                       TrianglesVector* triangles) const {
  string obj_file_name = FindFileWithObjExtension();
  ifstream file(obj_file_name);
  if (!file) {
    throw std::runtime_error(
        "Error opening file \"" + obj_file_name + "\".");
  }

  std::string line;
  int line_number = 0;
  int maximum_index = 0;
  while (!file.eof()) {
    ++line_number;
    std::getline(file, line);
    std::stringstream ss(line);
    std::string key;
    ss >> key;

    if (key == "v") {
      // Reads a 3D vertex.
      double x, y, z;
      ss >> x; ss >> y; ss >> z;
      if (ss.fail()) {
        throw std::runtime_error(
            "In file \"" + obj_file_name + "\" "
            "(line " + std::to_string(line_number) + "). "
            "Vertex in the wrong format.");
      }
      vertices->push_back(Vector3d(x, y, z));
    } else if (key == "f") {
      // Reads the connectivity for a single triangle.
      std::vector<int> indices;
      int index;
      while (ss >> index) {
        // Checks that index >= 1.
        if (index < 1) {
          throw std::runtime_error(
              "In file \"" + obj_file_name + "\" "
              "(line " + std::to_string(line_number) + "). "
              "Invalid vertex index is " + std::to_string(index) + " < 1.");
        }
        maximum_index = std::max(maximum_index, index);

        // Ignores line until the next whitespace.
        // This effectively ignores texture coordinates and normals.
        // The first entry always corresponds to an index in the face.
        ss.ignore(line.size(), ' ');
        if (ss.fail()) {
          throw std::runtime_error(
              "In file \"" + obj_file_name + "\" "
              "(line " + std::to_string(line_number) + "). "
              "Triangle face in the wrong format.");
        }
        indices.push_back(index);
      }
      if (indices.size() != 3) {
        throw std::runtime_error(
            "In file \"" + obj_file_name + "\" "
            "(line " + std::to_string(line_number) + "). "
            "Only triangular faces supported. However "
            + std::to_string(indices.size()) + " indices are provided.");
      }
      triangles->push_back(Vector3i(indices[0]-1, indices[1]-1, indices[2]-1));
    }
  }

  // Verifies that the number of vertices provided equals the maximum index
  // referenced when defining faces.
  if (maximum_index != vertices->size()) {
    throw std::runtime_error(
        "In file \"" + obj_file_name + "\". "
        "The number of vertices provided is " +
            std::to_string(vertices->size()) + ". "
        "However the maximum index referenced in defining faces is " +
            std::to_string(maximum_index) + ".");
  }
}

Mesh *Mesh::clone() const { return new Mesh(*this); }

void Mesh::getPoints(Eigen::Matrix3Xd &point_matrix) const {
  extractMeshVertices(point_matrix);
}

void Mesh::getBoundingBoxPoints(Matrix3Xd &bbox_points) const {
  Matrix3Xd mesh_vertices;
  extractMeshVertices(mesh_vertices);

  Vector3d min_pos = mesh_vertices.rowwise().minCoeff();
  Vector3d max_pos = mesh_vertices.rowwise().maxCoeff();

  bbox_points.resize(Eigen::NoChange, NUM_BBOX_POINTS);
  bbox_points << min_pos(0), min_pos(0), min_pos(0), min_pos(0), max_pos(0),
      max_pos(0), max_pos(0), max_pos(0), min_pos(1), min_pos(1), max_pos(1),
      max_pos(1), min_pos(1), min_pos(1), max_pos(1), max_pos(1), min_pos(2),
      max_pos(2), min_pos(2), max_pos(2), min_pos(2), max_pos(2), min_pos(2),
      max_pos(2);
}

ostream &operator<<(ostream &out, const Mesh &mm) {
  out << static_cast<const Geometry &>(mm) << ", " << mm.scale << ", "
      << mm.filename << ", " << mm.resolved_filename << ", " << mm.root_dir;
  return out;
}

MeshPoints::MeshPoints(const Eigen::Matrix3Xd &points)
    : Geometry(MESH_POINTS), points(points) {}

MeshPoints *MeshPoints::clone() const { return new MeshPoints(*this); }

void MeshPoints::getPoints(Eigen::Matrix3Xd &point_matrix) const {
  point_matrix = points;
}

void MeshPoints::getBoundingBoxPoints(Matrix3Xd &bbox_points) const {
  Vector3d min_pos = points.rowwise().minCoeff();
  Vector3d max_pos = points.rowwise().maxCoeff();

  bbox_points.resize(Eigen::NoChange, NUM_BBOX_POINTS);
  bbox_points << min_pos(0), min_pos(0), min_pos(0), min_pos(0), max_pos(0),
      max_pos(0), max_pos(0), max_pos(0), min_pos(1), min_pos(1), max_pos(1),
      max_pos(1), min_pos(1), min_pos(1), max_pos(1), max_pos(1), min_pos(2),
      max_pos(2), min_pos(2), max_pos(2), min_pos(2), max_pos(2), min_pos(2),
      max_pos(2);
}

ostream &operator<<(ostream &out, const MeshPoints &mp) {
  out << static_cast<const Geometry &>(mp) << ",\n" << mp.points;
  return out;
}

}  // namespace DrakeShapes
<commit_msg>Changes the strong conditon maximum_index=vertices->size() for maximum_index>vertices.size()<commit_after>#include "Geometry.h"

#include <cstdio>
#include <fstream>
#include <stdexcept>

#include "spruce.hh"

using std::string;
using std::ostream;
using std::istringstream;
using std::ifstream;

using Eigen::Vector3i;
using Eigen::Vector3d;
using Eigen::RowVectorXd;
using Eigen::Matrix3Xd;
using Eigen::Matrix3Xi;

namespace DrakeShapes {
const int Geometry::NUM_BBOX_POINTS = 8;
const int Sphere::NUM_POINTS = 1;
const int Capsule::NUM_POINTS = 2;

string ShapeToString(Shape ss) {
  switch (ss) {
    case UNKNOWN:
      return "UNKNOWN";
    case BOX:
      return "BOX";
    case SPHERE:
      return "SPHERE";
    case CYLINDER:
      return "CYLINDER";
    case MESH:
      return "MESH";
    case MESH_POINTS:
      return "MESH_POINTS";
    case CAPSULE:
      return "CAPSULE";
  }
  return "UNDEFINED";
}

Geometry::Geometry() : shape(UNKNOWN) {}

Geometry::Geometry(const Geometry &other) { shape = other.getShape(); }

Geometry::Geometry(Shape shape) : shape(shape) {}

Shape Geometry::getShape() const { return shape; }

Geometry *Geometry::clone() const { return new Geometry(*this); }

void Geometry::getPoints(Matrix3Xd &points) const { points = Matrix3Xd(); }

void Geometry::getBoundingBoxPoints(Matrix3Xd &points) const {
  points = Matrix3Xd();
}

void Geometry::getBoundingBoxPoints(double x_half_width, double y_half_width,
                                    double z_half_width,
                                    Eigen::Matrix3Xd &points) const {
  // Return axis-aligned bounding-box vertices
  points.resize(3, NUM_BBOX_POINTS);

  RowVectorXd cx(NUM_BBOX_POINTS), cy(NUM_BBOX_POINTS), cz(NUM_BBOX_POINTS);
  cx << -1, 1, 1, -1, -1, 1, 1, -1;
  cy << 1, 1, 1, 1, -1, -1, -1, -1;
  cz << 1, 1, -1, -1, -1, -1, 1, 1;
  cx = cx * x_half_width;
  cy = cy * y_half_width;
  cz = cz * z_half_width;

  points << cx, cy, cz;
}

ostream &operator<<(ostream &out, const Geometry &gg) {
  out << ShapeToString(gg.getShape()) << ", " << gg.NUM_BBOX_POINTS;
  return out;
}

Sphere::Sphere(double radius) : Geometry(SPHERE), radius(radius) {}

Sphere *Sphere::clone() const { return new Sphere(*this); }

void Sphere::getPoints(Matrix3Xd &points) const {
  points = Matrix3Xd::Zero(3, NUM_POINTS);
}

void Sphere::getBoundingBoxPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(radius, radius, radius, points);
}

void Sphere::getTerrainContactPoints(Matrix3Xd &points) const {
  if (radius < 1e-6)
    getPoints(points);
  else
    points = Matrix3Xd();
}

ostream &operator<<(ostream &out, const Sphere &ss) {
  out << static_cast<const Geometry &>(ss) << ", " << ss.radius << ", "
      << ss.NUM_POINTS;
  return out;
}

Box::Box(const Eigen::Vector3d &size) : Geometry(BOX), size(size) {}

Box *Box::clone() const { return new Box(*this); }

void Box::getPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(size(0) / 2.0, size(1) / 2.0, size(2) / 2.0,
                                 points);
}

void Box::getBoundingBoxPoints(Matrix3Xd &points) const { getPoints(points); }

void Box::getTerrainContactPoints(Matrix3Xd &points) const {
  getPoints(points);
}

ostream &operator<<(ostream &out, const Box &bb) {
  out << static_cast<const Geometry &>(bb) << ", " << bb.size.transpose();
  return out;
}

Cylinder::Cylinder(double radius, double length)
    : Geometry(CYLINDER), radius(radius), length(length) {}

Cylinder *Cylinder::clone() const { return new Cylinder(*this); }

void Cylinder::getPoints(Matrix3Xd &points) const {
  static bool warnOnce = true;
  if (warnOnce) {
    std::cerr << "Warning: DrakeShapes::Cylinder::getPoints(): "
        "This method returns the vertices of the cylinder''s bounding-box."
         << std::endl;
    warnOnce = false;
  }

  getBoundingBoxPoints(points);
}

void Cylinder::getBoundingBoxPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(radius, radius, length / 2.0, points);
}

ostream &operator<<(ostream &out, const Cylinder &cc) {
  out << static_cast<const Geometry &>(cc) << ", " << cc.radius << ", "
      << cc.length;
  return out;
}

Capsule::Capsule(double radius, double length)
    : Geometry(CAPSULE), radius(radius), length(length) {}

Capsule *Capsule::clone() const { return new Capsule(*this); }

void Capsule::getPoints(Matrix3Xd &points) const {
  // Return segment end-points
  points.resize(Eigen::NoChange, NUM_POINTS);
  RowVectorXd cx = RowVectorXd::Zero(NUM_POINTS);
  RowVectorXd cy = RowVectorXd::Zero(NUM_POINTS);
  RowVectorXd cz = RowVectorXd::Zero(NUM_POINTS);
  cz << length / 2.0, -length / 2.0;

  points << cx, cy, cz;
}

void Capsule::getBoundingBoxPoints(Matrix3Xd &points) const {
  Geometry::getBoundingBoxPoints(radius, radius, (length / 2.0 + radius),
                                 points);
}

ostream &operator<<(ostream &out, const Capsule &cc) {
  out << static_cast<const Geometry &>(cc) << ", " << cc.radius << ", "
      << cc.length;
  return out;
}

Mesh::Mesh(const string &filename)
    : Geometry(MESH), scale(1.0, 1.0, 1.0), filename(filename) {}

Mesh::Mesh(const string &filename, const string &resolved_filename)
    : Geometry(MESH),
      scale(1.0, 1.0, 1.0),
      filename(filename),
      resolved_filename(resolved_filename) {}

bool Mesh::extractMeshVertices(Matrix3Xd& vertex_coordinates) const {
  if (resolved_filename.empty()) return false;

  string obj_file_name = FindFileWithObjExtension();
  ifstream file(obj_file_name);
  if (!file) {
    throw std::runtime_error(
        "Error opening file \"" + obj_file_name + "\".");
  }

  string line;
  // Count the number of vertices and resize vertex_coordinates.
  int num_vertices = 0;
  while (getline(file, line)) {
    istringstream iss(line);
    string type;
    if (iss >> type && type == "v") {
      ++num_vertices;
    }
  }
  vertex_coordinates.resize(3, num_vertices);

  file.clear();
  file.seekg(0, file.beg);

  double d;
  int j = 0;
  while (getline(file, line)) {
    istringstream iss(line);
    string type;
    if (iss >> type && type == "v") {
      int i = 0;
      while (iss >> d) {
        vertex_coordinates(i++, j) = d;
      }
      ++j;
    }
  }
  return true;
}

string Mesh::FindFileWithObjExtension() const {
  spruce::path spath(resolved_filename);
  string ext = spath.extension();
  std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);

  if (ext.compare(".obj") == 0) {
    // Checks if the file with the obj extension exists.
    if (!spath.exists()) {
      throw std::runtime_error(
          "Unable to open file \"" + spath.getStr() + "\".");
    }
  } else {
    // Tries changing the extension to obj.
    spath.setExtension(".obj");
    if (!spath.exists()) {
      throw std::runtime_error(
          "Unable to resolve an obj file from the filename \""
              + spath.getStr() + "\" provided.");
    }
  }

  return spath.getStr();
}

void Mesh::LoadObjFile(PointsVector* vertices,
                       TrianglesVector* triangles) const {
  string obj_file_name = FindFileWithObjExtension();
  ifstream file(obj_file_name);
  if (!file) {
    throw std::runtime_error(
        "Error opening file \"" + obj_file_name + "\".");
  }

  std::string line;
  int line_number = 0;
  int maximum_index = 0;
  while (!file.eof()) {
    ++line_number;
    std::getline(file, line);
    std::stringstream ss(line);
    std::string key;
    ss >> key;

    if (key == "v") {
      // Reads a 3D vertex.
      double x, y, z;
      ss >> x; ss >> y; ss >> z;
      if (ss.fail()) {
        throw std::runtime_error(
            "In file \"" + obj_file_name + "\" "
            "(line " + std::to_string(line_number) + "). "
            "Vertex in the wrong format.");
      }
      vertices->push_back(Vector3d(x, y, z));
    } else if (key == "f") {
      // Reads the connectivity for a single triangle.
      std::vector<int> indices;
      int index;
      while (ss >> index) {
        // Checks that index >= 1.
        if (index < 1) {
          throw std::runtime_error(
              "In file \"" + obj_file_name + "\" "
              "(line " + std::to_string(line_number) + "). "
              "Invalid vertex index is " + std::to_string(index) + " < 1.");
        }
        maximum_index = std::max(maximum_index, index);

        // Ignores line until the next whitespace.
        // This effectively ignores texture coordinates and normals.
        // The first entry always corresponds to an index in the face.
        ss.ignore(line.size(), ' ');
        if (ss.fail()) {
          throw std::runtime_error(
              "In file \"" + obj_file_name + "\" "
              "(line " + std::to_string(line_number) + "). "
              "Triangle face in the wrong format.");
        }
        indices.push_back(index);
      }
      if (indices.size() != 3) {
        throw std::runtime_error(
            "In file \"" + obj_file_name + "\" "
            "(line " + std::to_string(line_number) + "). "
            "Only triangular faces supported. However "
            + std::to_string(indices.size()) + " indices are provided.");
      }
      triangles->push_back(Vector3i(indices[0]-1, indices[1]-1, indices[2]-1));
    }
  }

  // Verifies that the maximum index referenced when defining faces does not
  // exceed the number of vertices.
  if (maximum_index > vertices->size()) {
    throw std::runtime_error(
        "In file \"" + obj_file_name + "\". "
        "The maximum index referenced in defining faces (" +
            std::to_string(maximum_index) + ") "
        "exceeds the number of vertices (" +
            std::to_string(vertices->size()) + ". ");
  }
}

Mesh *Mesh::clone() const { return new Mesh(*this); }

void Mesh::getPoints(Eigen::Matrix3Xd &point_matrix) const {
  extractMeshVertices(point_matrix);
}

void Mesh::getBoundingBoxPoints(Matrix3Xd &bbox_points) const {
  Matrix3Xd mesh_vertices;
  extractMeshVertices(mesh_vertices);

  Vector3d min_pos = mesh_vertices.rowwise().minCoeff();
  Vector3d max_pos = mesh_vertices.rowwise().maxCoeff();

  bbox_points.resize(Eigen::NoChange, NUM_BBOX_POINTS);
  bbox_points << min_pos(0), min_pos(0), min_pos(0), min_pos(0), max_pos(0),
      max_pos(0), max_pos(0), max_pos(0), min_pos(1), min_pos(1), max_pos(1),
      max_pos(1), min_pos(1), min_pos(1), max_pos(1), max_pos(1), min_pos(2),
      max_pos(2), min_pos(2), max_pos(2), min_pos(2), max_pos(2), min_pos(2),
      max_pos(2);
}

ostream &operator<<(ostream &out, const Mesh &mm) {
  out << static_cast<const Geometry &>(mm) << ", " << mm.scale << ", "
      << mm.filename << ", " << mm.resolved_filename << ", " << mm.root_dir;
  return out;
}

MeshPoints::MeshPoints(const Eigen::Matrix3Xd &points)
    : Geometry(MESH_POINTS), points(points) {}

MeshPoints *MeshPoints::clone() const { return new MeshPoints(*this); }

void MeshPoints::getPoints(Eigen::Matrix3Xd &point_matrix) const {
  point_matrix = points;
}

void MeshPoints::getBoundingBoxPoints(Matrix3Xd &bbox_points) const {
  Vector3d min_pos = points.rowwise().minCoeff();
  Vector3d max_pos = points.rowwise().maxCoeff();

  bbox_points.resize(Eigen::NoChange, NUM_BBOX_POINTS);
  bbox_points << min_pos(0), min_pos(0), min_pos(0), min_pos(0), max_pos(0),
      max_pos(0), max_pos(0), max_pos(0), min_pos(1), min_pos(1), max_pos(1),
      max_pos(1), min_pos(1), min_pos(1), max_pos(1), max_pos(1), min_pos(2),
      max_pos(2), min_pos(2), max_pos(2), min_pos(2), max_pos(2), min_pos(2),
      max_pos(2);
}

ostream &operator<<(ostream &out, const MeshPoints &mp) {
  out << static_cast<const Geometry &>(mp) << ",\n" << mp.points;
  return out;
}

}  // namespace DrakeShapes
<|endoftext|>


<commit_before>#include <ir/index_manager/index/ParallelTermPosition.h>

#include <algorithm>

using namespace izenelib::ir::indexmanager;

ParallelTermPosition::ParallelTermPosition(collectionid_t colID, IndexReader* pIndexReader, vector<string>& properties)
        :colID_(colID)
        ,pIndexReader_(pIndexReader)
        ,properties_(properties)
{
}

ParallelTermPosition::~ParallelTermPosition()
{
    for (map<string, TermPositions*>::iterator iter = termPositionMap_.begin(); iter != termPositionMap_.end(); ++iter)
        delete iter->second;
    termPositionMap_.clear();
    for (map<string, TermReader*>::iterator iter = termReaderMap_.begin(); iter != termReaderMap_.end(); ++iter)
        delete iter->second;
    termReaderMap_.clear();
}

bool ParallelTermPosition::seek(termid_t termID)
{
    bool find = false;

    for (vector<string>::iterator iter = properties_.begin(); iter != properties_.end(); ++iter)
    {
        Term term((*iter).c_str(),termID);
        TermReader* pTermReader = pIndexReader_->getTermReader(colID_);
        bool localFind = pTermReader->seek(&term);
        find = find ||localFind;
        if (localFind)
        {
            TermPositions* pPositions = pTermReader->termPositions();
            termReaderMap_.insert(make_pair((*iter), pTermReader));
            termPositionMap_.insert(make_pair((*iter), pPositions));
            flagMap_.insert(make_pair((*iter), true));
        }
        else
            delete pTermReader;
    }
    return find;
}

bool ParallelTermPosition::next(vector<string>& properties, docid_t& docid)
{
    bool hasNext = false;
    docid_t minDocID = 0xFFFFFFFF;
    //flagMap_ is to indicate whether a certain property should be moved forward.
    for (map<string, bool>::iterator iter = flagMap_.begin(); iter != flagMap_.end(); ++iter)
    {
        if (iter->second)
        {
            TermPositions* pPosition = termPositionMap_[iter->first];
            bool local_hasNext = pPosition->next();
            hasNext = hasNext || local_hasNext;
            if (!local_hasNext)
            {
                flagMap_[iter->first] = false;
                currDocMap_[iter->first]= 0xFFFFFFFF;	///Add by Yingfeng 2009.08.27
                continue;
            }
            docid_t curr_docid = pPosition->doc();
            currDocMap_[iter->first] = curr_docid;
            iter->second = true;
            if (curr_docid < minDocID)
                minDocID = curr_docid;
        }
    }
    for (map<string, bool>::iterator iter = flagMap_.begin(); iter != flagMap_.end(); ++iter)
    {
        if (!iter->second)
        {
            if (currDocMap_[iter->first]<= minDocID)
            {
                flagMap_[iter->first] = true;
                minDocID = currDocMap_[iter->first];
            }
        }
    }
    if (!hasNext)
    {
        return false;
    }

    docid = minDocID;
	cout<<"docid!!! "<<docid<<endl;

    for (map<string, docid_t>::iterator iter = currDocMap_.begin(); iter != currDocMap_.end(); ++iter)
    {
        if (iter->second == minDocID)
        {
            properties.push_back(iter->first);
            flagMap_[iter->first] = true;
        }
        else
        {
            flagMap_[iter->first] = false;
        }
    }
    return true;
}

void ParallelTermPosition::getPositions(string& property, boost::shared_ptr<std::deque<unsigned int> >& positions, freq_t& tf, freq_t& doclen)
{
    TermPositions* pPositions =  termPositionMap_[property];
    loc_t pos = pPositions->nextPosition();
    loc_t charpos = pPositions->nextPosition();
    while (pos != BAD_POSITION)
    {
        positions->push_back(pos);
        pos = pPositions->nextPosition();
        charpos = pPositions->nextPosition();
    }
    tf = pPositions->freq();
    doclen = pPositions->docLength();
}

void ParallelTermPosition::getPositions(string& property, boost::shared_ptr<std::deque< std::pair<unsigned int,unsigned int> > >& positions,
	freq_t& tf, freq_t& doclen)
{
    TermPositions* pPositions =  termPositionMap_[property];
    loc_t pos = pPositions->nextPosition();
    loc_t charpos = pPositions->nextPosition();

    while (pos != BAD_POSITION)
    {
        positions->push_back(make_pair(pos,charpos));
        pos = pPositions->nextPosition();
        charpos = pPositions->nextPosition();
    }
    tf = pPositions->freq();
    doclen = pPositions->docLength();
}

void ParallelTermPosition::get_df_and_ctf(termid_t termID, DocumentFrequencyInProperties& dfmap, CollectionTermFrequencyInProperties& ctfmap)
{
    for (map<string, TermPositions*>::iterator iter = termPositionMap_.begin(); iter != termPositionMap_.end(); ++iter)
    {
        DocumentFrequencyInProperties::iterator df_iter = dfmap.insert(std::make_pair(iter->first, ID_FREQ_MAP_T())).first;
        df_iter->second.insert(make_pair(termID, (float)iter->second->docFreq()));

        CollectionTermFrequencyInProperties::iterator ctf_iter = ctfmap.insert(std::make_pair(iter->first, ID_FREQ_MAP_T())).first;
        ctf_iter->second.insert(make_pair(termID, (float)iter->second->getCTF()));
    }
}
<commit_msg>remove log<commit_after>#include <ir/index_manager/index/ParallelTermPosition.h>

#include <algorithm>

using namespace izenelib::ir::indexmanager;

ParallelTermPosition::ParallelTermPosition(collectionid_t colID, IndexReader* pIndexReader, vector<string>& properties)
        :colID_(colID)
        ,pIndexReader_(pIndexReader)
        ,properties_(properties)
{
}

ParallelTermPosition::~ParallelTermPosition()
{
    for (map<string, TermPositions*>::iterator iter = termPositionMap_.begin(); iter != termPositionMap_.end(); ++iter)
        delete iter->second;
    termPositionMap_.clear();
    for (map<string, TermReader*>::iterator iter = termReaderMap_.begin(); iter != termReaderMap_.end(); ++iter)
        delete iter->second;
    termReaderMap_.clear();
}

bool ParallelTermPosition::seek(termid_t termID)
{
    bool find = false;

    for (vector<string>::iterator iter = properties_.begin(); iter != properties_.end(); ++iter)
    {
        Term term((*iter).c_str(),termID);
        TermReader* pTermReader = pIndexReader_->getTermReader(colID_);
        bool localFind = pTermReader->seek(&term);
        find = find ||localFind;
        if (localFind)
        {
            TermPositions* pPositions = pTermReader->termPositions();
            termReaderMap_.insert(make_pair((*iter), pTermReader));
            termPositionMap_.insert(make_pair((*iter), pPositions));
            flagMap_.insert(make_pair((*iter), true));
        }
        else
            delete pTermReader;
    }
    return find;
}

bool ParallelTermPosition::next(vector<string>& properties, docid_t& docid)
{
    bool hasNext = false;
    docid_t minDocID = 0xFFFFFFFF;
    //flagMap_ is to indicate whether a certain property should be moved forward.
    for (map<string, bool>::iterator iter = flagMap_.begin(); iter != flagMap_.end(); ++iter)
    {
        if (iter->second)
        {
            TermPositions* pPosition = termPositionMap_[iter->first];
            bool local_hasNext = pPosition->next();
            hasNext = hasNext || local_hasNext;
            if (!local_hasNext)
            {
                flagMap_[iter->first] = false;
                currDocMap_[iter->first]= 0xFFFFFFFF;	///Add by Yingfeng 2009.08.27
                continue;
            }
            docid_t curr_docid = pPosition->doc();
            currDocMap_[iter->first] = curr_docid;
            iter->second = true;
            if (curr_docid < minDocID)
                minDocID = curr_docid;
        }
    }
    for (map<string, bool>::iterator iter = flagMap_.begin(); iter != flagMap_.end(); ++iter)
    {
        if (!iter->second)
        {
            if (currDocMap_[iter->first]<= minDocID)
            {
                flagMap_[iter->first] = true;
                minDocID = currDocMap_[iter->first];
            }
        }
    }
    if (!hasNext)
    {
        return false;
    }

    docid = minDocID;

    for (map<string, docid_t>::iterator iter = currDocMap_.begin(); iter != currDocMap_.end(); ++iter)
    {
        if (iter->second == minDocID)
        {
            properties.push_back(iter->first);
            flagMap_[iter->first] = true;
        }
        else
        {
            flagMap_[iter->first] = false;
        }
    }
    return true;
}

void ParallelTermPosition::getPositions(string& property, boost::shared_ptr<std::deque<unsigned int> >& positions, freq_t& tf, freq_t& doclen)
{
    TermPositions* pPositions =  termPositionMap_[property];
    loc_t pos = pPositions->nextPosition();
    loc_t charpos = pPositions->nextPosition();
    while (pos != BAD_POSITION)
    {
        positions->push_back(pos);
        pos = pPositions->nextPosition();
        charpos = pPositions->nextPosition();
    }
    tf = pPositions->freq();
    doclen = pPositions->docLength();
}

void ParallelTermPosition::getPositions(string& property, boost::shared_ptr<std::deque< std::pair<unsigned int,unsigned int> > >& positions,
	freq_t& tf, freq_t& doclen)
{
    TermPositions* pPositions =  termPositionMap_[property];
    loc_t pos = pPositions->nextPosition();
    loc_t charpos = pPositions->nextPosition();

    while (pos != BAD_POSITION)
    {
        positions->push_back(make_pair(pos,charpos));
        pos = pPositions->nextPosition();
        charpos = pPositions->nextPosition();
    }
    tf = pPositions->freq();
    doclen = pPositions->docLength();
}

void ParallelTermPosition::get_df_and_ctf(termid_t termID, DocumentFrequencyInProperties& dfmap, CollectionTermFrequencyInProperties& ctfmap)
{
    for (map<string, TermPositions*>::iterator iter = termPositionMap_.begin(); iter != termPositionMap_.end(); ++iter)
    {
        DocumentFrequencyInProperties::iterator df_iter = dfmap.insert(std::make_pair(iter->first, ID_FREQ_MAP_T())).first;
        df_iter->second.insert(make_pair(termID, (float)iter->second->docFreq()));

        CollectionTermFrequencyInProperties::iterator ctf_iter = ctfmap.insert(std::make_pair(iter->first, ID_FREQ_MAP_T())).first;
        ctf_iter->second.insert(make_pair(termID, (float)iter->second->getCTF()));
    }
}
<|endoftext|>