<commit_before>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * 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 the <organization> 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 EARLIER MENTIONED AUTHORS ``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 <copyright holder> 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 "CppUTest/TestHarness.h"
#include "CppUTest/SimpleString.h"
#include "CppUTest/PlatformSpecificFunctions.h"
#include "CppUTest/TestMemoryAllocator.h"

TestMemoryAllocator* SimpleString::stringAllocator_ = NULL;

TestMemoryAllocator* SimpleString::getStringAllocator()
{
	if (stringAllocator_ == NULL)
		return defaultNewArrayAllocator();
	return stringAllocator_;
}

void SimpleString::setStringAllocator(TestMemoryAllocator* allocator)
{
	stringAllocator_ = allocator;
}

/* Avoid using the memory leak detector INSIDE SimpleString as its used inside the detector */
char* SimpleString::allocStringBuffer(size_t _size)
{
	return getStringAllocator()->alloc_memory(_size, __FILE__, __LINE__);
}

void SimpleString::deallocStringBuffer(char* str)
{
	getStringAllocator()->free_memory(str, __FILE__, __LINE__);
}

char* SimpleString::getEmptyString() const
{
	char* empty = allocStringBuffer(1);
	empty[0] = '\0';
	return empty;
}
SimpleString::SimpleString(const char *otherBuffer)
{
	if (otherBuffer == 0) {
		buffer_ = getEmptyString();
	}
	else {
		size_t len = PlatformSpecificStrLen(otherBuffer) + 1;
		buffer_ = allocStringBuffer(len);
		PlatformSpecificStrCpy(buffer_, otherBuffer);
	}
}

SimpleString::SimpleString(const char *other, size_t repeatCount)
{
	size_t len = PlatformSpecificStrLen(other) * repeatCount + 1;
	buffer_ = allocStringBuffer(len);
	char* next = buffer_;
	for (size_t i = 0; i < repeatCount; i++) {
		PlatformSpecificStrCpy(next, other);
		next += PlatformSpecificStrLen(other);
	}
	*next = 0;

}
SimpleString::SimpleString(const SimpleString& other)
{
	size_t len = other.size() + 1;
	buffer_ = allocStringBuffer(len);
	PlatformSpecificStrCpy(buffer_, other.buffer_);
}

SimpleString& SimpleString::operator=(const SimpleString& other)
{
	if (this != &other) {
		deallocStringBuffer(buffer_);
		size_t len = other.size() + 1;
		buffer_ = allocStringBuffer(len);
		PlatformSpecificStrCpy(buffer_, other.buffer_);
	}
	return *this;
}

bool SimpleString::contains(const SimpleString& other) const
{
	//strstr on some machines does not handle ""
	//the right way.  "" should be found in any string
	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
	else return PlatformSpecificStrStr(buffer_, other.buffer_) != 0;
}

bool SimpleString::containsNoCase(const SimpleString& other) const
{
	return toLower().contains(other.toLower());
}

bool SimpleString::startsWith(const SimpleString& other) const
{
	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
	else return PlatformSpecificStrStr(buffer_, other.buffer_) == buffer_;
}

bool SimpleString::endsWith(const SimpleString& other) const
{
	size_t buffer_length = PlatformSpecificStrLen(buffer_);
	size_t other_buffer_length = PlatformSpecificStrLen(other.buffer_);
	if (other_buffer_length == 0) return true;
	if (buffer_length == 0) return false;
	if (buffer_length < other_buffer_length) return false;
	return PlatformSpecificStrCmp(buffer_ + buffer_length - other_buffer_length, other.buffer_) == 0;
}

size_t SimpleString::count(const SimpleString& substr) const
{
	size_t num = 0;
	char* str = buffer_;
	while ((str = PlatformSpecificStrStr(str, substr.buffer_))) {
		num++;
		str++;
	}
	return num;
}

void SimpleString::split(const SimpleString& delimiter, SimpleStringCollection& col) const
{
	size_t num = count(delimiter);
	size_t extraEndToken = (endsWith(delimiter)) ? 0 : 1U;
	col.allocate(num + extraEndToken);

	char* str = buffer_;
	char* prev;
	for (size_t i = 0; i < num; ++i) {
		prev = str;
		str = PlatformSpecificStrStr(str, delimiter.buffer_) + 1;
		size_t len = (size_t) (str - prev);
		char* sub = allocStringBuffer(len + 1);
		PlatformSpecificStrNCpy(sub, prev, len);
		sub[len] = '\0';
		col[i] = sub;
		deallocStringBuffer(sub);
	}
	if (extraEndToken) {
		col[num] = str;
	}
}

void SimpleString::replace(char to, char with)
{
	size_t s = size();
	for (size_t i = 0; i < s; i++) {
		if (buffer_[i] == to) buffer_[i] = with;
	}
}

void SimpleString::replace(const char* to, const char* with)
{
	size_t c = count(to);
	size_t len = size();
	size_t tolen = PlatformSpecificStrLen(to);
	size_t withlen = PlatformSpecificStrLen(with);

	size_t newsize = len + (withlen * c) - (tolen * c) + 1;

	if (newsize) {
		char* newbuf = allocStringBuffer(newsize);
		for (size_t i = 0, j = 0; i < len;) {
			if (PlatformSpecificStrNCmp(&buffer_[i], to, tolen) == 0) {
				PlatformSpecificStrNCpy(&newbuf[j], with, withlen);
				j += withlen;
				i += tolen;
			}
			else {
				newbuf[j] = buffer_[i];
				j++;
				i++;
			}
		}
		deallocStringBuffer(buffer_);
		buffer_ = newbuf;
		buffer_[newsize - 1] = '\0';
	}
	else {
		buffer_ = getEmptyString();
		buffer_[0] = '\0';
	}
}

SimpleString SimpleString::toLower() const
{
	SimpleString str(*this);

	size_t str_size = str.size();
	for (size_t i = 0; i < str_size; i++)
		str.buffer_[i] = PlatformSpecificToLower(str.buffer_[i]);

	return str;
}

const char *SimpleString::asCharString() const
{
	return buffer_;
}

size_t SimpleString::size() const
{
	return PlatformSpecificStrLen(buffer_);
}

bool SimpleString::isEmpty() const
{
	return size() == 0;
}

SimpleString::~SimpleString()
{
	deallocStringBuffer(buffer_);
}

bool operator==(const SimpleString& left, const SimpleString& right)
{
	return 0 == PlatformSpecificStrCmp(left.asCharString(), right.asCharString());
}

bool SimpleString::equalsNoCase(const SimpleString& str) const
{
	return toLower() == str.toLower();
}

bool operator!=(const SimpleString& left, const SimpleString& right)
{
	return !(left == right);
}

SimpleString SimpleString::operator+(const SimpleString& rhs)
{
	SimpleString t(buffer_);
	t += rhs.buffer_;
	return t;
}

SimpleString& SimpleString::operator+=(const SimpleString& rhs)
{
	return operator+=(rhs.buffer_);
}

SimpleString& SimpleString::operator+=(const char* rhs)
{
	size_t len = this->size() + PlatformSpecificStrLen(rhs) + 1;
	char* tbuffer = allocStringBuffer(len);
	PlatformSpecificStrCpy(tbuffer, this->buffer_);
	PlatformSpecificStrCat(tbuffer, rhs);
	deallocStringBuffer(buffer_);
	buffer_ = tbuffer;
	return *this;
}

void SimpleString::padStringsToSameLength(SimpleString& str1, SimpleString& str2, char padCharacter)
{
	if (str1.size() > str2.size()) {
		padStringsToSameLength(str2, str1, padCharacter);
		return;
	}

	char pad[2];
	pad[0] = padCharacter;
	pad[1] = 0;
	str1 = SimpleString(pad, str2.size() - str1.size()) + str1;
}

SimpleString SimpleString::subString(size_t beginPos, size_t amount) const
{
	if (beginPos > size()-1) return "";

	SimpleString newString = buffer_ + beginPos;

	if (newString.size() > amount)
		newString.buffer_[amount] = '\0';

	return newString;
}

char SimpleString::at(int pos) const
{
	return buffer_[pos];
}

int SimpleString::find(char ch) const
{
	return findFrom(0, ch);
}

int SimpleString::findFrom(size_t starting_position, char ch) const
{
	size_t length = size();
	for (size_t i = starting_position; i < length; i++)
		if (buffer_[i] == ch) return (int) i;
	return -1;
}

SimpleString SimpleString::subStringFromTill(char startChar, char lastExcludedChar) const
{
	int beginPos = find(startChar);
	if (beginPos < 0) return "";

	int endPos = findFrom((size_t)beginPos, lastExcludedChar);
	if (endPos == -1) return subString((size_t)beginPos, size());

	return subString((size_t)beginPos, (size_t) (endPos - beginPos));
}

void SimpleString::copyToBuffer(char* bufferToCopy, size_t bufferSize) const
{
	if (bufferToCopy == NULL || bufferSize == 0) return;

	size_t sizeToCopy = (bufferSize-1 < size()) ? bufferSize-1 : size();

	PlatformSpecificStrNCpy(bufferToCopy, buffer_, sizeToCopy);
	bufferToCopy[sizeToCopy] = '\0';

}

SimpleString StringFrom(bool value)
{
	return SimpleString(StringFromFormat("%s", value ? "true" : "false"));
}

SimpleString StringFrom(const char *value)
{
	return SimpleString(value);
}

SimpleString StringFromOrNull(const char * expected)
{
    return (expected) ? StringFrom(expected) : "(null)";
}

SimpleString StringFrom(int value)
{
	return StringFromFormat("%d", value);
}

SimpleString StringFrom(long value)
{
	return StringFromFormat("%ld", value);
}

SimpleString StringFrom(const void* value)
{
	return SimpleString("0x") + HexStringFrom(value);
}

SimpleString HexStringFrom(long value)
{
	return StringFromFormat("%lx", value);
}

static long convertPointerToLongValue(const void* value)
{
	/*
	 * This way of converting also can convert a 64bit pointer in a 32bit integer by truncating.
	 * This isn't the right way to convert pointers values and need to change by implementing a
	 * proper portable way to convert pointers to strings.
	 */
	long* long_value = (long*) &value;
	return *long_value;
}

SimpleString HexStringFrom(const void* value)
{
	return StringFromFormat("%lx", convertPointerToLongValue(value));
}

SimpleString StringFrom(double value, int precision)
{
	return StringFromFormat("%.*g", precision, value);
}

SimpleString StringFrom(char value)
{
	return StringFromFormat("%c", value);
}

SimpleString StringFrom(const SimpleString& value)
{
	return SimpleString(value);
}

SimpleString StringFromFormat(const char* format, ...)
{
	SimpleString resultString;
	va_list arguments;
	va_start(arguments, format);

	resultString = VStringFromFormat(format, arguments);
	va_end(arguments);
	return resultString;
}

SimpleString StringFrom(unsigned int i)
{
	return StringFromFormat("%10u (0x%08x)", i, i);
}

#if CPPUTEST_USE_STD_CPP_LIB

#include <string>

SimpleString StringFrom(const std::string& value)
{
	return SimpleString(value.c_str());
}

SimpleString StringFrom(unsigned long i)
{
	return StringFromFormat("%lu (0x%lx)", i, i);
}

#endif

//Kludge to get a va_copy in VC++ V6
#ifndef va_copy
#define va_copy(copy, original) copy = original;
#endif

SimpleString VStringFromFormat(const char* format, va_list args)
{
	va_list argsCopy;
	va_copy(argsCopy, args);
	enum
	{
		sizeOfdefaultBuffer = 100
	};
	char defaultBuffer[sizeOfdefaultBuffer];
	SimpleString resultString;

	size_t size = (size_t)PlatformSpecificVSNprintf(defaultBuffer, sizeOfdefaultBuffer, format, args);
	if (size < sizeOfdefaultBuffer) {
		resultString = SimpleString(defaultBuffer);
	}
	else {
		size_t newBufferSize = size + 1;
		char* newBuffer = SimpleString::allocStringBuffer(newBufferSize);
		PlatformSpecificVSNprintf(newBuffer, newBufferSize, format, argsCopy);
		resultString = SimpleString(newBuffer);

		SimpleString::deallocStringBuffer(newBuffer);
	}
	va_end(argsCopy);
	return resultString;
}

SimpleStringCollection::SimpleStringCollection()
{
	collection_ = 0;
	size_ = 0;
}

void SimpleStringCollection::allocate(size_t _size)
{
	if (collection_) delete[] collection_;

	size_ = _size;
	collection_ = new SimpleString[size_];
}

SimpleStringCollection::~SimpleStringCollection()
{
	delete[] (collection_);
}

size_t SimpleStringCollection::size() const
{
	return size_;
}

SimpleString& SimpleStringCollection::operator[](size_t index)
{
	if (index >= size_) {
		empty_ = "";
		return empty_;
	}

	return collection_[index];
}

<commit_msg>Converted StrCpy into StrNCpy<commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * 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 the <organization> 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 EARLIER MENTIONED AUTHORS ``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 <copyright holder> 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 "CppUTest/TestHarness.h"
#include "CppUTest/SimpleString.h"
#include "CppUTest/PlatformSpecificFunctions.h"
#include "CppUTest/TestMemoryAllocator.h"

TestMemoryAllocator* SimpleString::stringAllocator_ = NULL;

TestMemoryAllocator* SimpleString::getStringAllocator()
{
	if (stringAllocator_ == NULL)
		return defaultNewArrayAllocator();
	return stringAllocator_;
}

void SimpleString::setStringAllocator(TestMemoryAllocator* allocator)
{
	stringAllocator_ = allocator;
}

/* Avoid using the memory leak detector INSIDE SimpleString as its used inside the detector */
char* SimpleString::allocStringBuffer(size_t _size)
{
	return getStringAllocator()->alloc_memory(_size, __FILE__, __LINE__);
}

void SimpleString::deallocStringBuffer(char* str)
{
	getStringAllocator()->free_memory(str, __FILE__, __LINE__);
}

char* SimpleString::getEmptyString() const
{
	char* empty = allocStringBuffer(1);
	empty[0] = '\0';
	return empty;
}
SimpleString::SimpleString(const char *otherBuffer)
{
	if (otherBuffer == 0) {
		buffer_ = getEmptyString();
	}
	else {
		size_t len = PlatformSpecificStrLen(otherBuffer) + 1;
		buffer_ = allocStringBuffer(len);
		PlatformSpecificStrNCpy(buffer_, otherBuffer, len);
	}
}

SimpleString::SimpleString(const char *other, size_t repeatCount)
{
  size_t otherStringLength = PlatformSpecificStrLen(other);
	size_t len = otherStringLength * repeatCount + 1;
	buffer_ = allocStringBuffer(len);
	char* next = buffer_;
	for (size_t i = 0; i < repeatCount; i++) {
		PlatformSpecificStrNCpy(next, other, otherStringLength);
		next += otherStringLength;
	}
	*next = 0;

}
SimpleString::SimpleString(const SimpleString& other)
{
	size_t len = other.size() + 1;
	buffer_ = allocStringBuffer(len);
	PlatformSpecificStrNCpy(buffer_, other.buffer_, len);
}

SimpleString& SimpleString::operator=(const SimpleString& other)
{
	if (this != &other) {
		deallocStringBuffer(buffer_);
		size_t len = other.size() + 1;
		buffer_ = allocStringBuffer(len);
		PlatformSpecificStrNCpy(buffer_, other.buffer_, len);
	}
	return *this;
}

bool SimpleString::contains(const SimpleString& other) const
{
	//strstr on some machines does not handle ""
	//the right way.  "" should be found in any string
	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
	else return PlatformSpecificStrStr(buffer_, other.buffer_) != 0;
}

bool SimpleString::containsNoCase(const SimpleString& other) const
{
	return toLower().contains(other.toLower());
}

bool SimpleString::startsWith(const SimpleString& other) const
{
	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
	else return PlatformSpecificStrStr(buffer_, other.buffer_) == buffer_;
}

bool SimpleString::endsWith(const SimpleString& other) const
{
	size_t buffer_length = PlatformSpecificStrLen(buffer_);
	size_t other_buffer_length = PlatformSpecificStrLen(other.buffer_);
	if (other_buffer_length == 0) return true;
	if (buffer_length == 0) return false;
	if (buffer_length < other_buffer_length) return false;
	return PlatformSpecificStrCmp(buffer_ + buffer_length - other_buffer_length, other.buffer_) == 0;
}

size_t SimpleString::count(const SimpleString& substr) const
{
	size_t num = 0;
	char* str = buffer_;
	while ((str = PlatformSpecificStrStr(str, substr.buffer_))) {
		num++;
		str++;
	}
	return num;
}

void SimpleString::split(const SimpleString& delimiter, SimpleStringCollection& col) const
{
	size_t num = count(delimiter);
	size_t extraEndToken = (endsWith(delimiter)) ? 0 : 1U;
	col.allocate(num + extraEndToken);

	char* str = buffer_;
	char* prev;
	for (size_t i = 0; i < num; ++i) {
		prev = str;
		str = PlatformSpecificStrStr(str, delimiter.buffer_) + 1;
		size_t len = (size_t) (str - prev);
		char* sub = allocStringBuffer(len + 1);
		PlatformSpecificStrNCpy(sub, prev, len);
		sub[len] = '\0';
		col[i] = sub;
		deallocStringBuffer(sub);
	}
	if (extraEndToken) {
		col[num] = str;
	}
}

void SimpleString::replace(char to, char with)
{
	size_t s = size();
	for (size_t i = 0; i < s; i++) {
		if (buffer_[i] == to) buffer_[i] = with;
	}
}

void SimpleString::replace(const char* to, const char* with)
{
	size_t c = count(to);
	size_t len = size();
	size_t tolen = PlatformSpecificStrLen(to);
	size_t withlen = PlatformSpecificStrLen(with);

	size_t newsize = len + (withlen * c) - (tolen * c) + 1;

	if (newsize) {
		char* newbuf = allocStringBuffer(newsize);
		for (size_t i = 0, j = 0; i < len;) {
			if (PlatformSpecificStrNCmp(&buffer_[i], to, tolen) == 0) {
				PlatformSpecificStrNCpy(&newbuf[j], with, withlen);
				j += withlen;
				i += tolen;
			}
			else {
				newbuf[j] = buffer_[i];
				j++;
				i++;
			}
		}
		deallocStringBuffer(buffer_);
		buffer_ = newbuf;
		buffer_[newsize - 1] = '\0';
	}
	else {
		buffer_ = getEmptyString();
		buffer_[0] = '\0';
	}
}

SimpleString SimpleString::toLower() const
{
	SimpleString str(*this);

	size_t str_size = str.size();
	for (size_t i = 0; i < str_size; i++)
		str.buffer_[i] = PlatformSpecificToLower(str.buffer_[i]);

	return str;
}

const char *SimpleString::asCharString() const
{
	return buffer_;
}

size_t SimpleString::size() const
{
	return PlatformSpecificStrLen(buffer_);
}

bool SimpleString::isEmpty() const
{
	return size() == 0;
}

SimpleString::~SimpleString()
{
	deallocStringBuffer(buffer_);
}

bool operator==(const SimpleString& left, const SimpleString& right)
{
	return 0 == PlatformSpecificStrCmp(left.asCharString(), right.asCharString());
}

bool SimpleString::equalsNoCase(const SimpleString& str) const
{
	return toLower() == str.toLower();
}

bool operator!=(const SimpleString& left, const SimpleString& right)
{
	return !(left == right);
}

SimpleString SimpleString::operator+(const SimpleString& rhs)
{
	SimpleString t(buffer_);
	t += rhs.buffer_;
	return t;
}

SimpleString& SimpleString::operator+=(const SimpleString& rhs)
{
	return operator+=(rhs.buffer_);
}

SimpleString& SimpleString::operator+=(const char* rhs)
{
	size_t originalSize = this->size();
	size_t additionalStringSize = PlatformSpecificStrLen(rhs);
	size_t totalSizeOfNewBuffer = originalSize + additionalStringSize + 1;
	char* tbuffer = allocStringBuffer(totalSizeOfNewBuffer);
	PlatformSpecificStrNCpy(tbuffer, this->buffer_, originalSize);
	PlatformSpecificStrNCpy(tbuffer + originalSize, rhs, additionalStringSize + 1);
	deallocStringBuffer(buffer_);
	buffer_ = tbuffer;
	return *this;
}

void SimpleString::padStringsToSameLength(SimpleString& str1, SimpleString& str2, char padCharacter)
{
	if (str1.size() > str2.size()) {
		padStringsToSameLength(str2, str1, padCharacter);
		return;
	}

	char pad[2];
	pad[0] = padCharacter;
	pad[1] = 0;
	str1 = SimpleString(pad, str2.size() - str1.size()) + str1;
}

SimpleString SimpleString::subString(size_t beginPos, size_t amount) const
{
	if (beginPos > size()-1) return "";

	SimpleString newString = buffer_ + beginPos;

	if (newString.size() > amount)
		newString.buffer_[amount] = '\0';

	return newString;
}

char SimpleString::at(int pos) const
{
	return buffer_[pos];
}

int SimpleString::find(char ch) const
{
	return findFrom(0, ch);
}

int SimpleString::findFrom(size_t starting_position, char ch) const
{
	size_t length = size();
	for (size_t i = starting_position; i < length; i++)
		if (buffer_[i] == ch) return (int) i;
	return -1;
}

SimpleString SimpleString::subStringFromTill(char startChar, char lastExcludedChar) const
{
	int beginPos = find(startChar);
	if (beginPos < 0) return "";

	int endPos = findFrom((size_t)beginPos, lastExcludedChar);
	if (endPos == -1) return subString((size_t)beginPos, size());

	return subString((size_t)beginPos, (size_t) (endPos - beginPos));
}

void SimpleString::copyToBuffer(char* bufferToCopy, size_t bufferSize) const
{
	if (bufferToCopy == NULL || bufferSize == 0) return;

	size_t sizeToCopy = (bufferSize-1 < size()) ? bufferSize-1 : size();

	PlatformSpecificStrNCpy(bufferToCopy, buffer_, sizeToCopy);
	bufferToCopy[sizeToCopy] = '\0';

}

SimpleString StringFrom(bool value)
{
	return SimpleString(StringFromFormat("%s", value ? "true" : "false"));
}

SimpleString StringFrom(const char *value)
{
	return SimpleString(value);
}

SimpleString StringFromOrNull(const char * expected)
{
    return (expected) ? StringFrom(expected) : "(null)";
}

SimpleString StringFrom(int value)
{
	return StringFromFormat("%d", value);
}

SimpleString StringFrom(long value)
{
	return StringFromFormat("%ld", value);
}

SimpleString StringFrom(const void* value)
{
	return SimpleString("0x") + HexStringFrom(value);
}

SimpleString HexStringFrom(long value)
{
	return StringFromFormat("%lx", value);
}

static long convertPointerToLongValue(const void* value)
{
	/*
	 * This way of converting also can convert a 64bit pointer in a 32bit integer by truncating.
	 * This isn't the right way to convert pointers values and need to change by implementing a
	 * proper portable way to convert pointers to strings.
	 */
	long* long_value = (long*) &value;
	return *long_value;
}

SimpleString HexStringFrom(const void* value)
{
	return StringFromFormat("%lx", convertPointerToLongValue(value));
}

SimpleString StringFrom(double value, int precision)
{
	return StringFromFormat("%.*g", precision, value);
}

SimpleString StringFrom(char value)
{
	return StringFromFormat("%c", value);
}

SimpleString StringFrom(const SimpleString& value)
{
	return SimpleString(value);
}

SimpleString StringFromFormat(const char* format, ...)
{
	SimpleString resultString;
	va_list arguments;
	va_start(arguments, format);

	resultString = VStringFromFormat(format, arguments);
	va_end(arguments);
	return resultString;
}

SimpleString StringFrom(unsigned int i)
{
	return StringFromFormat("%10u (0x%08x)", i, i);
}

#if CPPUTEST_USE_STD_CPP_LIB

#include <string>

SimpleString StringFrom(const std::string& value)
{
	return SimpleString(value.c_str());
}

SimpleString StringFrom(unsigned long i)
{
	return StringFromFormat("%lu (0x%lx)", i, i);
}

#endif

//Kludge to get a va_copy in VC++ V6
#ifndef va_copy
#define va_copy(copy, original) copy = original;
#endif

SimpleString VStringFromFormat(const char* format, va_list args)
{
	va_list argsCopy;
	va_copy(argsCopy, args);
	enum
	{
		sizeOfdefaultBuffer = 100
	};
	char defaultBuffer[sizeOfdefaultBuffer];
	SimpleString resultString;

	size_t size = (size_t)PlatformSpecificVSNprintf(defaultBuffer, sizeOfdefaultBuffer, format, args);
	if (size < sizeOfdefaultBuffer) {
		resultString = SimpleString(defaultBuffer);
	}
	else {
		size_t newBufferSize = size + 1;
		char* newBuffer = SimpleString::allocStringBuffer(newBufferSize);
		PlatformSpecificVSNprintf(newBuffer, newBufferSize, format, argsCopy);
		resultString = SimpleString(newBuffer);

		SimpleString::deallocStringBuffer(newBuffer);
	}
	va_end(argsCopy);
	return resultString;
}

SimpleStringCollection::SimpleStringCollection()
{
	collection_ = 0;
	size_ = 0;
}

void SimpleStringCollection::allocate(size_t _size)
{
	if (collection_) delete[] collection_;

	size_ = _size;
	collection_ = new SimpleString[size_];
}

SimpleStringCollection::~SimpleStringCollection()
{
	delete[] (collection_);
}

size_t SimpleStringCollection::size() const
{
	return size_;
}

SimpleString& SimpleStringCollection::operator[](size_t index)
{
	if (index >= size_) {
		empty_ = "";
		return empty_;
	}

	return collection_[index];
}

<|endoftext|>


<commit_before>#pragma once

#include "SuperComponent.hpp"

namespace Video {
    namespace Geometry {
        class Geometry3D;
    }
}

namespace Component {
    /// %Component providing geometry to an entity.
    class Mesh : public SuperComponent {
        public:
            /// Create new mesh.
            Mesh();

            /// Destructor.
            ~Mesh() override;

            /// Save the component.
            /**
             * @return JSON value to be stored on disk.
             */
            Json::Value Save() const override;

            /// Geometry data.
            /**
             * Default: nullptr
             */
            Video::Geometry::Geometry3D* geometry = nullptr;

            /// Highlight selection.
            /**
            * @return True if selected else false.
            */
            bool GetSelected() const;

            /// Highlight selection.
            /**
            * @param Set true if mesh is selected, else false.
            */
            void SetSelected(bool value);

    private:
        /// If mesh is selected in the editor.
        bool isSelected;

    };
}
<commit_msg>Added proper comments.<commit_after>#pragma once

#include "SuperComponent.hpp"

namespace Video {
    namespace Geometry {
        class Geometry3D;
    }
}

namespace Component {
    /// %Component providing geometry to an entity.
    class Mesh : public SuperComponent {
        public:
            /// Create new mesh.
            Mesh();

            /// Destructor.
            ~Mesh() override;

            /// Save the component.
            /**
             * @return JSON value to be stored on disk.
             */
            Json::Value Save() const override;

            /// Geometry data.
            /**
             * Default: nullptr
             */
            Video::Geometry::Geometry3D* geometry = nullptr;

            /// Get mesh selection.
            /**
            * @return Bool Is this selected or not.
            */
            bool GetSelected() const;

            /// Set mesh selection.
            /**
            * @param Value If selected or not.
            */
            void SetSelected(bool value);

    private:
        bool isSelected;

    };
}
<|endoftext|>


<commit_before>//============================================================================
// Name        : Monte_carlo.cpp
// Author      : Rafael
// Version     :
// Copyright   : MIT
// Description : Hello World in C++, Ansi-style
// referencias:
// 1 - http://ta.twi.tudelft.nl/mf/users/oosterle/oosterlee/lec8-hit-2009.pdf
// 2 - Sadiku. M.N.O - Numeral Techniques in Electromagnetics with MATLAB
// 3 - http://ww2.odu.edu/~agodunov/computing/programs/cpp/dmc_int1.cpp
// 4 - https://github.com/s9w/articles/blob/master/perf%20cpp%20random.md - comparacao entre os metodos de gerar numeros aleatorios
//http://www.cs.dartmouth.edu/~wjarosz/publications/dissertation/appendixA.pdf

// AJUDOU SOBRE GERAR DOUBLE:
//http://stackoverflow.com/questions/32071721/error-in-using-mt19937-with-random-device-as-static-class-members
//http://physics.clarku.edu/courses/125/gtcdraft/chap11.pdf
//http://stackoverflow.com/questions/24334012/best-way-to-seed-mt19937-64-for-monte-carlo-simulations
//

/*
Artigos sobre geracao de aleatorios e monte carlo
http://journals.aps.org/pre/abstract/10.1103/PhysRevE.75.066701
 */
/*
Metodos para gerar aleatorios:
usado pelo chrome - xorshift128+						XX - Implementado GenerateNumbersXOR.h
padrao do c++ 11 - mt19937 								XX - Implementado GenerateNumbers.h
descrito pelo numerical recipes pg 366- Ran 			XX - Implementado GenerateNumbersNR.h
 */

/*
 * Testar pelo método analitico as integrais
 * http://www.wolframalpha.com/examples/Integrals.html
 */

/** Alguns codigos fontes de MonteCarlo
 * http://ww2.odu.edu/~agodunov/computing/programs/cpp/dmc_int1.cpp
 * http://ww2.odu.edu/~agodunov/computing/programs/cpp/mc_int_nd.cpp
 */

/** tipos de metodos para integrar com o MonteCarlo
 * https://www.unige.ch/sciences/astro/files/2713/8971/4086/3_Paltani_MonteCarlo.pdf
 * -Strafiel sampling
 * -Importance sampling
 */
//============================================================================

/*
 * Adicionar novas formas de gerar numeros aleatorios
 * implementar novos metodos de monte carlo, importance
 * compilar
 * g++ -Wall -g -std=c++11 MonteCarloIntegration.cpp MonteCarloCrudeN.cpp GenerateNumbersNR.h -o MonteCarlo.o
 *
 */
#include <iostream>
#include <random>

#include <string>
#include <math.h>
//#include "MonteCarloCrude.h"
#include "MonteCarloCrudeN.h"
#include <time.h>
#include <array>
#include <fstream>
#include <limits>
#include <iomanip>
#include <type_traits>
#include <algorithm>

using namespace std;

// prototipo das funcoes

/**
 *
 * @param x - uma funcao com apenas uma dimensao
 * @return retorna a funcao
 */
double funcao(double x);
double funcaoN(double x[], int n, double limiteX, double limiteY, double limiteZ, double step);

/**
 * Voce define a funcao que deve ser integrada
 * @param x Parametro de entrada da funcao
 * @return
 */
double funcao(double x) {
	double y;
	/**
	 * I = x dx
	 * resultado analitico: "http://www.wolframalpha.com/input/?i=int+x+dx+from+0+to+10"
	 */
	y = x;

	return y;
}
// classe para comprar numeros de ponto flutuante
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
    almost_equal(T x, T y, int ulp)
{
    // the machine epsilon has to be scaled to the magnitude of the values used
    // and multiplied by the desired precision in ULPs (units in the last place)
    return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
    // unless the result is subnormal
           || std::abs(x-y) < std::numeric_limits<T>::min();

}

// estou usando a funcao do Alex Godunov
//	    for (j = 0; j < n; j = j+1)
//	      {
//	         y = y + x[j];
//	      }
//	    y = pow(y,2);

	    /** resultado analitico
	     * Wolfram: "http://www.wolframalpha.com/input/?i=int+x+%2B+y+%2B+z+dx+dy+dz%2C+x%3D0+to+1%2C+y%3D0+to+1%2C+z%3D0+to+1"
	     */

double funcaoN(double x[], int n, double limiteX, double limiteY, double limiteZ, double step) {
	 double y;
	  /* Funcao antiga
	    //   int j;
	    double gama_0 = 2.3562;
	    int a_0 = 5;
	    double c_a = 9.1439;
	    y = 0.0;

	    double raizG_0 = sqrt( pow(x[0],2) + pow(x[1],2) + pow(x[2],2)  );
	    if( raizG_0 == 0  ){

	    	y = a_0;
	    }else if(raizG_0 < 1){

	    	y = a_0 * ((  sin(gama_0*raizG_0)) / (gama_0*raizG_0)) ;

	    } else {

	    	y = c_a * (( exp( -gama_0*raizG_0)) / ( gama_0*raizG_0)) ;
	    }

	    y = pow(y,2);

	    double raiz_R =  sqrt( pow(limiteX - x[0],2) + pow(limiteY - x[1],2) + pow(limiteZ - x[2],2)  );

	    if(raiz_R >= step ){
	    	y/= raiz_R;

	    } else {
	    	y/= 2 * step;
	    }
	    /*

/*
		   // return y = x[0] + x[1] + x[2];
	    //return y = pow(x[0],2) + sin(x[1]) * exp(x[2]);
*/

//	    y = 2*pow(x[0],2) + 3*pow(x[1],2) + 4*pow(x[2],2);

	 //Valores Calculados para energia e constantes de normalização
	 double e_l0, e_l1, e_l2;
	 double gama1_l0, gama1_l1, gama1_l2, gama2_l0, gama2_l1, gama2_l2;
	 int czao_l0, czao_l1, czao_l2;
	 float azao_l0, azao_l1, azao_l2;

	 e_l0 = 53.7;
	 e_l1 = 198.5;
	 e_l2 = 289.8;

	 gama1_l0 = 2.1973;
	 gama1_l1 = 4.2248;
	 gama1_l2 = 5.1045;

	 gama2_l0 = 5.5800;
	 gama2_l1 = 4.2562;
	 gama2_l2 = 3.1477;

	 czao_l0 = 3;
	 czao_l1 = 6;
	 czao_l2 = 7;

	 azao_l0 = 281779;
	 azao_l1 = 5.9432;
	 azao_l2 = 7.2102;

	    return y;

	    //	    cout << "x1: "<< x[0] <<endl;
	    //	    cout << "y1: "<< x[1] <<endl;
	    //	    cout << "z1: "<< x[2] <<endl;

}

int main() {

	clock_t tStart = clock();
	// definindo a precisao de quando mostra os resultados
	cout.precision(5);
	cout.setf(ios::fixed | ios::showpoint);

/** MonteCarlo 1 dimensao

	//	double a, b, montecarlo, erro;
	//	int n;
	//	int ntimes;
//	a = 0.0;
//	b = 10.0;
//	n = 2;
//	ntimes = 16;
//	for (int var = 0; var <= ntimes; ++var) {
//
//		montecarlo = MonteCarloCrude::CrudeMonteCarlo(funcao, a, b, n, erro);
//
//		cout <<"N: " << n << " Monte: "<< montecarlo << " Erro:"<< erro << endl;
//		n = n * 2;
//	}

/** MonteCarlo n dimensoes
 * Parametros:
 * numeroIntegrais - quantidade de integrais, ex: dx, dy, dz...
 * L - Limite superior e inferior do somatorio da integral e limite do x,y,z das variaveis internas
 * limiteInferior - valor para o limite inferior do somatorio da integral
 * limiteSuperior - valor para o limite supeior do somatorio da integral
 * numeroInteracoes -  numero de chamadas para o montecarlo, quanto maior melhor, porem quanto maior maior tempo
 * step -  o passo de cada interacao
 * resultado -  valor retornado pelo metodo de montecarlo
 */
		const int numeroIntegrais = 3;
		int L = 1;
	    double limiteInferior[numeroIntegrais] = { -L, -L, -L};
	    double limiteSuperior[numeroIntegrais] = { L, L, L};
	    int numeroInteracoes = 100000;
	    double step=0.5;

	    double limiteX, limiteY, limiteZ;
	    double matrizMonte[int((L/0.25)+1)][int((L/0.25)+1)][int((L/0.25)+1)];
	    double resultado;
	    int aux_x, aux_y, aux_z;

aux_x = 0;
aux_y = 0;
aux_z = 0;

for (limiteX = -L, aux_x=0 ; limiteX <= L; limiteX+= step, ++aux_x) {
	for (limiteY = -L, aux_y=0 ; limiteY <= L; limiteY+= step, ++aux_y) {
		for (limiteZ = -L, aux_z=0 ; limiteZ <= L; limiteZ+= step, ++aux_z) {

			resultado = MonteCarloCrudeN::CrudeMonteCarloN(funcaoN, limiteInferior, limiteSuperior, numeroIntegrais, numeroInteracoes,limiteX, limiteY,limiteZ,step);
		      //  cout << "mN: " << mN << " Resul: "<< result << endl;
		        cout << "x " << limiteX << " y "<< limiteY << " z " <<limiteZ << " Resul "<< resultado << endl;
		     //   cout << "a_x " << aux_x << " a_y "<< aux_y << " a_z " <<aux_z << endl;

		       matrizMonte[aux_x][aux_y][aux_z] = resultado;

		}
	}
}

//Pegando a hora atual e definindo no nome do arquivo
time_t now;
struct tm *now_tm;
now = time(NULL);
now_tm = localtime(&now);
int hour = now_tm->tm_hour;
int min = now_tm->tm_min;
int sec = now_tm->tm_sec;

//Criando um arquivo para coloca os dados da matriz X	Y 	Z 	Resultado
ofstream myfile;
string arquivoNome = "matriz " + to_string(hour)+ ":" + to_string(min) + ":" + to_string(sec) + ".txt";
myfile.open (arquivoNome);
myfile << "X,\t" << "Y,\t" << "Z,\t"<< "Resultado\t" << endl;

// escrevendo resultado no arquivo
aux_x = 0;
aux_y = 0;
aux_z = 0;

for (limiteX = -L, aux_x=0 ; limiteX <= L; limiteX+= step, ++aux_x) {
	for (limiteY = -L, aux_y=0 ; limiteY <= L; limiteY+= step, ++aux_y) {
		for (limiteZ = -L, aux_z=0 ; limiteZ <= L; limiteZ+= step, ++aux_z) {

			//escrevendo no arquivo
			myfile << limiteX <<",\t"<< limiteY << ",\t" << limiteZ << ",\t" << matrizMonte[aux_x][aux_y][aux_z]  << "\t" << endl;

		}
	}

}

	    cout << "Time taken: " << (double)(clock() - tStart)/CLOCKS_PER_SEC << endl;

	return 0;
}

<commit_msg>tarefa2 - definindo funcao V11<commit_after>//============================================================================
// Name        : Monte_carlo.cpp
// Author      : Rafael
// Version     :
// Copyright   : MIT
// Description : Hello World in C++, Ansi-style
// referencias:
// 1 - http://ta.twi.tudelft.nl/mf/users/oosterle/oosterlee/lec8-hit-2009.pdf
// 2 - Sadiku. M.N.O - Numeral Techniques in Electromagnetics with MATLAB
// 3 - http://ww2.odu.edu/~agodunov/computing/programs/cpp/dmc_int1.cpp
// 4 - https://github.com/s9w/articles/blob/master/perf%20cpp%20random.md - comparacao entre os metodos de gerar numeros aleatorios
//http://www.cs.dartmouth.edu/~wjarosz/publications/dissertation/appendixA.pdf

// AJUDOU SOBRE GERAR DOUBLE:
//http://stackoverflow.com/questions/32071721/error-in-using-mt19937-with-random-device-as-static-class-members
//http://physics.clarku.edu/courses/125/gtcdraft/chap11.pdf
//http://stackoverflow.com/questions/24334012/best-way-to-seed-mt19937-64-for-monte-carlo-simulations
//

/*
Artigos sobre geracao de aleatorios e monte carlo
http://journals.aps.org/pre/abstract/10.1103/PhysRevE.75.066701
 */
/*
Metodos para gerar aleatorios:
usado pelo chrome - xorshift128+						XX - Implementado GenerateNumbersXOR.h
padrao do c++ 11 - mt19937 								XX - Implementado GenerateNumbers.h
descrito pelo numerical recipes pg 366- Ran 			XX - Implementado GenerateNumbersNR.h
 */

/*
 * Testar pelo método analitico as integrais
 * http://www.wolframalpha.com/examples/Integrals.html
 */

/** Alguns codigos fontes de MonteCarlo
 * http://ww2.odu.edu/~agodunov/computing/programs/cpp/dmc_int1.cpp
 * http://ww2.odu.edu/~agodunov/computing/programs/cpp/mc_int_nd.cpp
 */

/** tipos de metodos para integrar com o MonteCarlo
 * https://www.unige.ch/sciences/astro/files/2713/8971/4086/3_Paltani_MonteCarlo.pdf
 * -Strafiel sampling
 * -Importance sampling
 */
//============================================================================

/*
 * Adicionar novas formas de gerar numeros aleatorios
 * implementar novos metodos de monte carlo, importance
 * compilar
 * g++ -Wall -g -std=c++11 MonteCarloIntegration.cpp MonteCarloCrudeN.cpp GenerateNumbersNR.h -o MonteCarlo.o
 *
 */
#include <iostream>
#include <random>

#include <string>
#include <math.h>
//#include "MonteCarloCrude.h"
#include "MonteCarloCrudeN.h"
#include <time.h>
#include <array>
#include <fstream>
#include <limits>
#include <iomanip>
#include <type_traits>
#include <algorithm>

using namespace std;

// prototipo das funcoes

/**
 *
 * @param x - uma funcao com apenas uma dimensao
 * @return retorna a funcao
 */
double funcao(double x);
double funcaoN(double x[], int n, double limiteX, double limiteY, double limiteZ, double step);

/**
 * Voce define a funcao que deve ser integrada
 * @param x Parametro de entrada da funcao
 * @return
 */
double funcao(double x) {
	double y;
	/**
	 * I = x dx
	 * resultado analitico: "http://www.wolframalpha.com/input/?i=int+x+dx+from+0+to+10"
	 */
	y = x;

	return y;
}
// classe para comprar numeros de ponto flutuante
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
    almost_equal(T x, T y, int ulp)
{
    // the machine epsilon has to be scaled to the magnitude of the values used
    // and multiplied by the desired precision in ULPs (units in the last place)
    return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
    // unless the result is subnormal
           || std::abs(x-y) < std::numeric_limits<T>::min();

}

// estou usando a funcao do Alex Godunov
//	    for (j = 0; j < n; j = j+1)
//	      {
//	         y = y + x[j];
//	      }
//	    y = pow(y,2);

	    /** resultado analitico
	     * Wolfram: "http://www.wolframalpha.com/input/?i=int+x+%2B+y+%2B+z+dx+dy+dz%2C+x%3D0+to+1%2C+y%3D0+to+1%2C+z%3D0+to+1"
	     */

double funcaoN(double x[], int n, double limiteX, double limiteY, double limiteZ, double step) {
	 double y;
	  /* Funcao antiga
	    //   int j;
	    double gama_0 = 2.3562;
	    int a_0 = 5;
	    double c_a = 9.1439;
	    y = 0.0;

	    double raizG_0 = sqrt( pow(x[0],2) + pow(x[1],2) + pow(x[2],2)  );
	    if( raizG_0 == 0  ){

	    	y = a_0;
	    }else if(raizG_0 < 1){

	    	y = a_0 * ((  sin(gama_0*raizG_0)) / (gama_0*raizG_0)) ;

	    } else {

	    	y = c_a * (( exp( -gama_0*raizG_0)) / ( gama_0*raizG_0)) ;
	    }

	    y = pow(y,2);

	    double raiz_R =  sqrt( pow(limiteX - x[0],2) + pow(limiteY - x[1],2) + pow(limiteZ - x[2],2)  );

	    if(raiz_R >= step ){
	    	y/= raiz_R;

	    } else {
	    	y/= 2 * step;
	    }
	    /*

/*
		   // return y = x[0] + x[1] + x[2];
	    //return y = pow(x[0],2) + sin(x[1]) * exp(x[2]);
*/

//	    y = 2*pow(x[0],2) + 3*pow(x[1],2) + 4*pow(x[2],2);

	 //Valores Calculados para energia e constantes de normalização
	 double e_l0, e_l1, e_l2;
	 double gama1_l0, gama1_l1, gama1_l2, gama2_l0, gama2_l1, gama2_l2;
	 int czao_l0, czao_l1, czao_l2;
	 float azao_l0, azao_l1, azao_l2;

	 float V0;
	 double Y2;

	 e_l0 = 53.7;
	 e_l1 = 198.5;
	 e_l2 = 289.8;

	 gama1_l0 = 2.1973;
	 gama1_l1 = 4.2248;
	 gama1_l2 = 5.1045;

	 gama2_l0 = 5.5800;
	 gama2_l1 = 4.2562;
	 gama2_l2 = 3.1477;

	 czao_l0 = 3;
	 czao_l1 = 6;
	 czao_l2 = 7;

	 azao_l0 = 281779;
	 azao_l1 = 5.9432;
	 azao_l2 = 7.2102;

	 // valor calculado para o V0
	 V0 = -0.3697;

	 //definicao do Y2
	 Y2 = (15 / (8 * M_PI) ) * ((pow(x[0],2) + pow(x[1],2)) * pow(x[2],2) ) / ( pow(pow(x[0],2) + pow(x[1],2) + pow(x[2],2), 2 )  );

	 double R_Rc = sqrt( 		(pow(limiteX - x[0], 2) + 		pow(limiteY - x[1],2) +  			pow(limiteZ - x[2],2) ));

	 if( R_Rc < step){

		 R_Rc = 2 * step;

	 }

	    return y;

	    //	    cout << "x1: "<< x[0] <<endl;
	    //	    cout << "y1: "<< x[1] <<endl;
	    //	    cout << "z1: "<< x[2] <<endl;

}

int main() {

	clock_t tStart = clock();
	// definindo a precisao de quando mostra os resultados
	cout.precision(5);
	cout.setf(ios::fixed | ios::showpoint);

/** MonteCarlo 1 dimensao

	//	double a, b, montecarlo, erro;
	//	int n;
	//	int ntimes;
//	a = 0.0;
//	b = 10.0;
//	n = 2;
//	ntimes = 16;
//	for (int var = 0; var <= ntimes; ++var) {
//
//		montecarlo = MonteCarloCrude::CrudeMonteCarlo(funcao, a, b, n, erro);
//
//		cout <<"N: " << n << " Monte: "<< montecarlo << " Erro:"<< erro << endl;
//		n = n * 2;
//	}

/** MonteCarlo n dimensoes
 * Parametros:
 * numeroIntegrais - quantidade de integrais, ex: dx, dy, dz...
 * L - Limite superior e inferior do somatorio da integral e limite do x,y,z das variaveis internas
 * limiteInferior - valor para o limite inferior do somatorio da integral
 * limiteSuperior - valor para o limite supeior do somatorio da integral
 * numeroInteracoes -  numero de chamadas para o montecarlo, quanto maior melhor, porem quanto maior maior tempo
 * step -  o passo de cada interacao
 * resultado -  valor retornado pelo metodo de montecarlo
 */
		const int numeroIntegrais = 3;
		int L = 1;
	    double limiteInferior[numeroIntegrais] = { -L, -L, -L};
	    double limiteSuperior[numeroIntegrais] = { L, L, L};
	    int numeroInteracoes = 100000;
	    double step=0.5;

	    double limiteX, limiteY, limiteZ;
	    double matrizMonte[int((L/0.25)+1)][int((L/0.25)+1)][int((L/0.25)+1)];
	    double resultado;
	    int aux_x, aux_y, aux_z;

aux_x = 0;
aux_y = 0;
aux_z = 0;

for (limiteX = -L, aux_x=0 ; limiteX <= L; limiteX+= step, ++aux_x) {
	for (limiteY = -L, aux_y=0 ; limiteY <= L; limiteY+= step, ++aux_y) {
		for (limiteZ = -L, aux_z=0 ; limiteZ <= L; limiteZ+= step, ++aux_z) {

			resultado = MonteCarloCrudeN::CrudeMonteCarloN(funcaoN, limiteInferior, limiteSuperior, numeroIntegrais, numeroInteracoes,limiteX, limiteY,limiteZ,step);
		      //  cout << "mN: " << mN << " Resul: "<< result << endl;
		        cout << "x " << limiteX << " y "<< limiteY << " z " <<limiteZ << " Resul "<< resultado << endl;
		     //   cout << "a_x " << aux_x << " a_y "<< aux_y << " a_z " <<aux_z << endl;

		       matrizMonte[aux_x][aux_y][aux_z] = resultado;

		}
	}
}

//Pegando a hora atual e definindo no nome do arquivo
time_t now;
struct tm *now_tm;
now = time(NULL);
now_tm = localtime(&now);
int hour = now_tm->tm_hour;
int min = now_tm->tm_min;
int sec = now_tm->tm_sec;

//Criando um arquivo para coloca os dados da matriz X	Y 	Z 	Resultado
ofstream myfile;
string arquivoNome = "matriz " + to_string(hour)+ ":" + to_string(min) + ":" + to_string(sec) + ".txt";
myfile.open (arquivoNome);
myfile << "X,\t" << "Y,\t" << "Z,\t"<< "Resultado\t" << endl;

// escrevendo resultado no arquivo
aux_x = 0;
aux_y = 0;
aux_z = 0;

for (limiteX = -L, aux_x=0 ; limiteX <= L; limiteX+= step, ++aux_x) {
	for (limiteY = -L, aux_y=0 ; limiteY <= L; limiteY+= step, ++aux_y) {
		for (limiteZ = -L, aux_z=0 ; limiteZ <= L; limiteZ+= step, ++aux_z) {

			//escrevendo no arquivo
			myfile << limiteX <<",\t"<< limiteY << ",\t" << limiteZ << ",\t" << matrizMonte[aux_x][aux_y][aux_z]  << "\t" << endl;

		}
	}

}

	    cout << "Time taken: " << (double)(clock() - tStart)/CLOCKS_PER_SEC << endl;

	return 0;
}

<|endoftext|>


<commit_before>#include "cmm_socket_receiver.h"
#include "cmm_socket_sender.h"
#include <pthread.h>
#include "debug.h"
#include "timeops.h"
#include <vector>
using std::vector;

class ReadyIROB {
  public:
    bool operator()(PendingIROB *pi) {
        assert(pi);
        PendingReceiverIROB *pirob = static_cast<PendingReceiverIROB*>(pi);
        assert(pirob);
        return (pirob->is_complete() && pirob->is_released());
    }
};

CMMSocketReceiver::CMMSocketReceiver(CMMSocketImpl *sk_)
    : sk(sk_)
{
    handle(CMM_CONTROL_MSG_BEGIN_IROB, this,
           &CMMSocketReceiver::do_begin_irob);
    handle(CMM_CONTROL_MSG_END_IROB, this, &CMMSocketReceiver::do_end_irob);
    handle(CMM_CONTROL_MSG_IROB_CHUNK, this,
           &CMMSocketReceiver::do_irob_chunk);
    handle(CMM_CONTROL_MSG_DEFAULT_IROB, this,
           &CMMSocketReceiver::do_default_irob);
    handle(CMM_CONTROL_MSG_NEW_INTERFACE, this,
           &CMMSocketReceiver::do_new_interface);
    handle(CMM_CONTROL_MSG_DOWN_INTERFACE, this,
           &CMMSocketReceiver::do_down_interface);
    handle(CMM_CONTROL_MSG_ACK, this, &CMMSocketReceiver::do_ack);
    handle(CMM_CONTROL_MSG_GOODBYE, this, &CMMSocketReceiver::do_goodbye);
}

CMMSocketReceiver::~CMMSocketReceiver()
{
    stop();

    PendingIROBHash::accessor ac;
    while (pending_irobs.any(ac)) {
        PendingIROB *victim = ac->second;
        pending_irobs.erase(ac);
        delete victim;
        ac.release();
    }
}

void
CMMSocketReceiver::dispatch(struct CMMSocketControlHdr hdr)
{
    struct timeval now;
    TIME(now);
    dbgprintf("Receiver-scheduler got request: %s\n",
	      hdr.describe().c_str());
    CMMSocketScheduler<struct CMMSocketControlHdr>::dispatch(hdr);
}

void
CMMSocketReceiver::do_begin_irob(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_BEGIN_IROB);
    if (hdr.op.begin_irob.numdeps > 0) {
        assert(hdr.op.begin_irob.deps);
    }

    PendingIROB *pirob = new PendingReceiverIROB(hdr.op.begin_irob);
    PendingIROBHash::accessor ac;
    if (!pending_irobs.insert(ac, pirob)) {
        delete pirob;
        throw Exception::make("Tried to begin IROB that already exists",
                                  hdr);
    }

    if (hdr.op.begin_irob.numdeps > 0) {
        delete [] hdr.op.begin_irob.deps;
    }
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Receiver began IROB %d, took %lu.%06lu seconds\n",
	      ntohl(hdr.op.begin_irob.id), diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_end_irob(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_END_IROB);
    PendingIROBHash::accessor ac;
    irob_id_t id = ntohl(hdr.op.end_irob.id);
    if (!pending_irobs.find(ac, id)) {
        if (pending_irobs.past_irob_exists(id)) {
            throw Exception::make("Tried to end committed IROB", hdr);
        } else {
            throw Exception::make("Tried to end nonexistent IROB", hdr);
        }
    }
    PendingIROB *pirob = ac->second;
    assert(pirob);
    if (!pirob->finish()) {
        throw Exception::make("Tried to end already-done IROB", hdr);
    }

    PendingReceiverIROB *prirob = static_cast<PendingReceiverIROB*>(pirob);
    pending_irobs.release_if_ready(prirob, ReadyIROB());
    ac.release();

    //sk->sendr->ack(id);

    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Receiver ended IROB %d, took %lu.%06lu seconds\n",
	      id, diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_irob_chunk(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_IROB_CHUNK);
    irob_id_t id = ntohl(hdr.op.irob_chunk.id);
    PendingIROBHash::accessor ac;
    if (!pending_irobs.find(ac, id)) {
        if (pending_irobs.past_irob_exists(id)) {
            throw Exception::make("Tried to add to committed IROB", hdr);
        } else {
            throw Exception::make("Tried to add to nonexistent IROB", hdr);
        }
    }
    struct irob_chunk_data chunk;
    chunk.id = id;
    chunk.seqno = ntohl(hdr.op.irob_chunk.seqno);
    chunk.datalen = ntohl(hdr.op.irob_chunk.datalen);
    chunk.data = hdr.op.irob_chunk.data;

    PendingIROB *pirob = ac->second;
    assert(pirob);
    PendingReceiverIROB *prirob = static_cast<PendingReceiverIROB*>(pirob);
    assert(prirob);
    if (!prirob->add_chunk(chunk)) {
        throw Exception::make("Tried to add to completed IROB", hdr);
    } else {
	dbgprintf("Successfully added chunk %d to IROB %d\n",
		  chunk.seqno, id);
    }
    ac.release();

    sk->sendr->ack(id, chunk.seqno);
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Added and ACK'd chunk %d in IROB %d, took %lu.%06lu seconds\n",
	      chunk.seqno, id, diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_default_irob(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);

    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_DEFAULT_IROB);
    PendingIROB *pirob = new PendingReceiverIROB(hdr.op.default_irob);
    PendingIROBHash::accessor ac;
    if (!pending_irobs.insert(ac, pirob)) {
        delete pirob;
        throw Exception::make("Tried to add default IROB that already exists",
			      hdr);
    }

    /* missing ack */
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Received default IROB %d, took %lu.%06lu seconds\n",
	      ntohl(hdr.op.default_irob.id), diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_new_interface(struct CMMSocketControlHdr hdr)
{
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_NEW_INTERFACE);
    struct net_interface iface = {hdr.op.new_interface.ip_addr,
                                  hdr.op.new_interface.labels};
    sk->setup(iface, false);
}

void
CMMSocketReceiver::do_down_interface(struct CMMSocketControlHdr hdr)
{
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_DOWN_INTERFACE);
    struct net_interface iface = {hdr.op.down_interface.ip_addr};
    sk->teardown(iface, false);
}

void
CMMSocketReceiver::do_ack(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);

    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_ACK);
    sk->sendr->ack_received(ntohl(hdr.op.ack.id), ntohl(hdr.op.ack.seqno));

    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Receiver got ACK for IROB %d chunk %d, took %lu.%06lu seconds\n",
	      ntohl(hdr.op.ack.id), ntohl(hdr.op.ack.seqno),
	      diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_goodbye(struct CMMSocketControlHdr hdr)
{
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_GOODBYE);
    if (sk->sendr->is_shutting_down()) {
	/* I initiated the shutdown; this is the "FIN/ACK" */
	/* at this point, both sides have stopped sending. */
	sk->sendr->goodbye_acked();
    } else {
	/* The other side initiated the shutdown; this is the "FIN" */
	/* Send the "FIN/ACK" */
	sk->sendr->goodbye(true);
    }
    /* Note: the senders will still wait for all IROB chunks
     * to be ACK'd before finalizing the shutdown. */
}

void
CMMSocketReceiver::shutdown()
{
    pending_irobs.shutdown();
}

/* This is where all the scheduling logic happens.
 * This function decides how to pass IROB data to the application.
 *
 * Additionally, this function is the only place we need
 * to worry about race conditions with the Receiver thread.
 * Thus, the locking discipline of that thread will be informed
 * by whatever reads and writes are necessary here.
 *
 * Initial stab at requirements:
 *   This thread definitely needs to read from the pending_irobs
 *   data structure, to figure out what data to pass to the
 *   application.  It also needs to update this data structure
 *   and the past_irobs set as IROBs are committed.
 * Thought: we could make this function read-only by using the
 *   msg_queue to cause the Receiver thread to do any needed updates.
 */
/* TODO: nonblocking mode */
ssize_t
CMMSocketReceiver::recv(void *bufp, size_t len, int flags, u_long *recv_labels)
{
    vector<PendingReceiverIROB *> pirobs;
    char *buf = (char*)bufp;

    struct timeval begin, end, diff;
    TIME(begin);

    ssize_t bytes_ready = 0;
    while ((size_t)bytes_ready < len) {
	struct timeval one_begin, one_end, one_diff;
	TIME(one_begin);
        PendingReceiverIROB *pirob = pending_irobs.get_ready_irob();
	TIME(one_end);
	TIMEDIFF(one_begin, one_end, one_diff);
	dbgprintf("Getting one ready IROB took %lu.%06lu seconds\n",
		  one_diff.tv_sec, one_diff.tv_usec);
	if (!pirob) {
	    if (sk->sendr->is_shutting_down()) {
		return 0;
	    } else {
		assert(0); /* XXX: nonblocking case may return NULL */
	    }
	}

        /* after the IROB is returned here, no other thread will
         * unsafely modify it.
         * XXX: this will not be true if we allow get_next_irob
         * to return released, incomplete IROBs.
         * We could fix that by simply having a sentinel chunk
         * on the concurrent_queue of chunks. */

        assert(pirob->is_released());
        assert(pirob->is_complete()); /* XXX: see get_next_irob */

        ssize_t bytes = pirob->numbytes();
        assert(bytes > 0);
        bytes_ready += bytes;

        pirobs.push_back(pirob);

        if (!pirob->is_complete()) {
            break;
        }
    }
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("recv: gathering bytes took %lu.%06lu seconds\n",
	      diff.tv_sec, diff.tv_usec);

    TIME(begin);

    ssize_t bytes_passed = 0;
    bool partial_irob = false;
    for (size_t i = 0; i < pirobs.size(); i++) {
        PendingIROBHash::accessor ac;
        PendingReceiverIROB *pirob = pirobs[i];
        if (!pending_irobs.find(ac, pirob->id)) {
            assert(0);
        }
        assert(pirob == ac->second);
        if (i == 0) {
            if (recv_labels) {
                *recv_labels = pirob->send_labels;
            }
        }

        bytes_passed += pirob->read_data(buf + bytes_passed,
                                         len - bytes_passed);
        if (pirob->is_complete() && pirob->numbytes() == 0) {
            pending_irobs.erase(ac);
            pending_irobs.release_dependents(pirob, ReadyIROB());
            delete pirob;
        } else {
            if (!pirob->is_complete()) {
                /* This should still be the last one in the list,
                 * since it MUST finish before any IROB can be
                 * passed to the application. */
            }
            /* this should be true for at most the last IROB
             * in the vector */
            assert(!partial_irob);
            partial_irob = true;
            pending_irobs.partially_read(pirob);
        }
    }

    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("recv: Copying bytes took %lu.%06lu seconds\n",
	      diff.tv_sec, diff.tv_usec);
    dbgprintf("Passing bytes to application\n");
    return bytes_passed;
}

bool
CMMSocketReceiver::find_irob(PendingIROBHash::const_accessor& ac,
			     irob_id_t id)
{
    return pending_irobs.find(ac, id);
}
<commit_msg>Remember to release default IROBs as they arrive.<commit_after>#include "cmm_socket_receiver.h"
#include "cmm_socket_sender.h"
#include <pthread.h>
#include "debug.h"
#include "timeops.h"
#include <vector>
using std::vector;

class ReadyIROB {
  public:
    bool operator()(PendingIROB *pi) {
        assert(pi);
        PendingReceiverIROB *pirob = static_cast<PendingReceiverIROB*>(pi);
        assert(pirob);
        return (pirob->is_complete() && pirob->is_released());
    }
};

CMMSocketReceiver::CMMSocketReceiver(CMMSocketImpl *sk_)
    : sk(sk_)
{
    handle(CMM_CONTROL_MSG_BEGIN_IROB, this,
           &CMMSocketReceiver::do_begin_irob);
    handle(CMM_CONTROL_MSG_END_IROB, this, &CMMSocketReceiver::do_end_irob);
    handle(CMM_CONTROL_MSG_IROB_CHUNK, this,
           &CMMSocketReceiver::do_irob_chunk);
    handle(CMM_CONTROL_MSG_DEFAULT_IROB, this,
           &CMMSocketReceiver::do_default_irob);
    handle(CMM_CONTROL_MSG_NEW_INTERFACE, this,
           &CMMSocketReceiver::do_new_interface);
    handle(CMM_CONTROL_MSG_DOWN_INTERFACE, this,
           &CMMSocketReceiver::do_down_interface);
    handle(CMM_CONTROL_MSG_ACK, this, &CMMSocketReceiver::do_ack);
    handle(CMM_CONTROL_MSG_GOODBYE, this, &CMMSocketReceiver::do_goodbye);
}

CMMSocketReceiver::~CMMSocketReceiver()
{
    stop();

    PendingIROBHash::accessor ac;
    while (pending_irobs.any(ac)) {
        PendingIROB *victim = ac->second;
        pending_irobs.erase(ac);
        delete victim;
        ac.release();
    }
}

void
CMMSocketReceiver::dispatch(struct CMMSocketControlHdr hdr)
{
    struct timeval now;
    TIME(now);
    dbgprintf("Receiver-scheduler got request: %s\n",
	      hdr.describe().c_str());
    CMMSocketScheduler<struct CMMSocketControlHdr>::dispatch(hdr);
}

void
CMMSocketReceiver::do_begin_irob(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_BEGIN_IROB);
    if (hdr.op.begin_irob.numdeps > 0) {
        assert(hdr.op.begin_irob.deps);
    }

    PendingIROB *pirob = new PendingReceiverIROB(hdr.op.begin_irob);
    PendingIROBHash::accessor ac;
    if (!pending_irobs.insert(ac, pirob)) {
        delete pirob;
        throw Exception::make("Tried to begin IROB that already exists",
                                  hdr);
    }

    if (hdr.op.begin_irob.numdeps > 0) {
        delete [] hdr.op.begin_irob.deps;
    }
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Receiver began IROB %d, took %lu.%06lu seconds\n",
	      ntohl(hdr.op.begin_irob.id), diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_end_irob(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_END_IROB);
    PendingIROBHash::accessor ac;
    irob_id_t id = ntohl(hdr.op.end_irob.id);
    if (!pending_irobs.find(ac, id)) {
        if (pending_irobs.past_irob_exists(id)) {
            throw Exception::make("Tried to end committed IROB", hdr);
        } else {
            throw Exception::make("Tried to end nonexistent IROB", hdr);
        }
    }
    PendingIROB *pirob = ac->second;
    assert(pirob);
    if (!pirob->finish()) {
        throw Exception::make("Tried to end already-done IROB", hdr);
    }

    PendingReceiverIROB *prirob = static_cast<PendingReceiverIROB*>(pirob);
    pending_irobs.release_if_ready(prirob, ReadyIROB());
    ac.release();

    //sk->sendr->ack(id);

    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Receiver ended IROB %d, took %lu.%06lu seconds\n",
	      id, diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_irob_chunk(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_IROB_CHUNK);
    irob_id_t id = ntohl(hdr.op.irob_chunk.id);
    PendingIROBHash::accessor ac;
    if (!pending_irobs.find(ac, id)) {
        if (pending_irobs.past_irob_exists(id)) {
            throw Exception::make("Tried to add to committed IROB", hdr);
        } else {
            throw Exception::make("Tried to add to nonexistent IROB", hdr);
        }
    }
    struct irob_chunk_data chunk;
    chunk.id = id;
    chunk.seqno = ntohl(hdr.op.irob_chunk.seqno);
    chunk.datalen = ntohl(hdr.op.irob_chunk.datalen);
    chunk.data = hdr.op.irob_chunk.data;

    PendingIROB *pirob = ac->second;
    assert(pirob);
    PendingReceiverIROB *prirob = static_cast<PendingReceiverIROB*>(pirob);
    assert(prirob);
    if (!prirob->add_chunk(chunk)) {
        throw Exception::make("Tried to add to completed IROB", hdr);
    } else {
	dbgprintf("Successfully added chunk %d to IROB %d\n",
		  chunk.seqno, id);
    }
    ac.release();

    sk->sendr->ack(id, chunk.seqno);
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Added and ACK'd chunk %d in IROB %d, took %lu.%06lu seconds\n",
	      chunk.seqno, id, diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_default_irob(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);

    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_DEFAULT_IROB);
    PendingIROB *pirob = new PendingReceiverIROB(hdr.op.default_irob);
    PendingIROBHash::accessor ac;
    if (!pending_irobs.insert(ac, pirob)) {
        delete pirob;
        throw Exception::make("Tried to add default IROB that already exists",
			      hdr);
    }

    PendingReceiverIROB *prirob = static_cast<PendingReceiverIROB*>(pirob);
    pending_irobs.release_if_ready(prirob, ReadyIROB());
    ac.release();

    sk->sendr->ack(ntohl(hdr.op.default_irob.id));
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Received default IROB %d, took %lu.%06lu seconds\n",
	      ntohl(hdr.op.default_irob.id), diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_new_interface(struct CMMSocketControlHdr hdr)
{
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_NEW_INTERFACE);
    struct net_interface iface = {hdr.op.new_interface.ip_addr,
                                  hdr.op.new_interface.labels};
    sk->setup(iface, false);
}

void
CMMSocketReceiver::do_down_interface(struct CMMSocketControlHdr hdr)
{
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_DOWN_INTERFACE);
    struct net_interface iface = {hdr.op.down_interface.ip_addr};
    sk->teardown(iface, false);
}

void
CMMSocketReceiver::do_ack(struct CMMSocketControlHdr hdr)
{
    struct timeval begin, end, diff;
    TIME(begin);

    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_ACK);
    sk->sendr->ack_received(ntohl(hdr.op.ack.id), ntohl(hdr.op.ack.seqno));

    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("Receiver got ACK for IROB %d chunk %d, took %lu.%06lu seconds\n",
	      ntohl(hdr.op.ack.id), ntohl(hdr.op.ack.seqno),
	      diff.tv_sec, diff.tv_usec);
}

void
CMMSocketReceiver::do_goodbye(struct CMMSocketControlHdr hdr)
{
    assert(ntohs(hdr.type) == CMM_CONTROL_MSG_GOODBYE);
    if (sk->sendr->is_shutting_down()) {
	/* I initiated the shutdown; this is the "FIN/ACK" */
	/* at this point, both sides have stopped sending. */
	sk->sendr->goodbye_acked();
    } else {
	/* The other side initiated the shutdown; this is the "FIN" */
	/* Send the "FIN/ACK" */
	sk->sendr->goodbye(true);
    }
    /* Note: the senders will still wait for all IROB chunks
     * to be ACK'd before finalizing the shutdown. */
}

void
CMMSocketReceiver::shutdown()
{
    pending_irobs.shutdown();
}

/* This is where all the scheduling logic happens.
 * This function decides how to pass IROB data to the application.
 *
 * Additionally, this function is the only place we need
 * to worry about race conditions with the Receiver thread.
 * Thus, the locking discipline of that thread will be informed
 * by whatever reads and writes are necessary here.
 *
 * Initial stab at requirements:
 *   This thread definitely needs to read from the pending_irobs
 *   data structure, to figure out what data to pass to the
 *   application.  It also needs to update this data structure
 *   and the past_irobs set as IROBs are committed.
 * Thought: we could make this function read-only by using the
 *   msg_queue to cause the Receiver thread to do any needed updates.
 */
/* TODO: nonblocking mode */
ssize_t
CMMSocketReceiver::recv(void *bufp, size_t len, int flags, u_long *recv_labels)
{
    vector<PendingReceiverIROB *> pirobs;
    char *buf = (char*)bufp;

    struct timeval begin, end, diff;
    TIME(begin);

    ssize_t bytes_ready = 0;
    while ((size_t)bytes_ready < len) {
	struct timeval one_begin, one_end, one_diff;
	TIME(one_begin);
        PendingReceiverIROB *pirob = pending_irobs.get_ready_irob();
	TIME(one_end);
	TIMEDIFF(one_begin, one_end, one_diff);
	dbgprintf("Getting one ready IROB took %lu.%06lu seconds\n",
		  one_diff.tv_sec, one_diff.tv_usec);
	if (!pirob) {
	    if (sk->sendr->is_shutting_down()) {
		return 0;
	    } else {
		assert(0); /* XXX: nonblocking case may return NULL */
	    }
	}

        /* after the IROB is returned here, no other thread will
         * unsafely modify it.
         * XXX: this will not be true if we allow get_next_irob
         * to return released, incomplete IROBs.
         * We could fix that by simply having a sentinel chunk
         * on the concurrent_queue of chunks. */

        assert(pirob->is_released());
        assert(pirob->is_complete()); /* XXX: see get_next_irob */

        ssize_t bytes = pirob->numbytes();
        assert(bytes > 0);
        bytes_ready += bytes;

        pirobs.push_back(pirob);

        if (!pirob->is_complete()) {
            break;
        }
    }
    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("recv: gathering bytes took %lu.%06lu seconds\n",
	      diff.tv_sec, diff.tv_usec);

    TIME(begin);

    ssize_t bytes_passed = 0;
    bool partial_irob = false;
    for (size_t i = 0; i < pirobs.size(); i++) {
        PendingIROBHash::accessor ac;
        PendingReceiverIROB *pirob = pirobs[i];
        if (!pending_irobs.find(ac, pirob->id)) {
            assert(0);
        }
        assert(pirob == ac->second);
        if (i == 0) {
            if (recv_labels) {
                *recv_labels = pirob->send_labels;
            }
        }

        bytes_passed += pirob->read_data(buf + bytes_passed,
                                         len - bytes_passed);
        if (pirob->is_complete() && pirob->numbytes() == 0) {
            pending_irobs.erase(ac);
            pending_irobs.release_dependents(pirob, ReadyIROB());
            delete pirob;
        } else {
            if (!pirob->is_complete()) {
                /* This should still be the last one in the list,
                 * since it MUST finish before any IROB can be
                 * passed to the application. */
            }
            /* this should be true for at most the last IROB
             * in the vector */
            assert(!partial_irob);
            partial_irob = true;
            pending_irobs.partially_read(pirob);
        }
    }

    TIME(end);
    TIMEDIFF(begin, end, diff);
    dbgprintf("recv: Copying bytes took %lu.%06lu seconds\n",
	      diff.tv_sec, diff.tv_usec);
    dbgprintf("Passing bytes to application\n");
    return bytes_passed;
}

bool
CMMSocketReceiver::find_irob(PendingIROBHash::const_accessor& ac,
			     irob_id_t id)
{
    return pending_irobs.find(ac, id);
}
<|endoftext|>


<commit_before>#pragma once

#include <eosio/chain/wasm_interface.hpp>
#include <eosio/chain/webassembly/wavm.hpp>
#include <eosio/chain/webassembly/binaryen.hpp>
#include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/wasm_eosio_injection.hpp>

#include "IR/Module.h"
#include "Runtime/Intrinsics.h"
#include "Platform/Platform.h"
#include "WAST/WAST.h"
#include "IR/Validate.h"

using namespace fc;
using namespace eosio::chain::webassembly;
using namespace IR;
using namespace Runtime;

namespace eosio { namespace chain {

   struct wasm_interface_impl {
      wasm_interface_impl(wasm_interface::vm_type vm) {
         if(vm == wasm_interface::vm_type::wavm)
            runtime_interface = std::make_unique<webassembly::wavm::wavm_runtime>();
         else if(vm == wasm_interface::vm_type::binaryen)
            runtime_interface = std::make_unique<webassembly::binaryen::binaryen_runtime>();
         else
            FC_THROW("wasm_interface_impl fall through");
      }

      std::vector<uint8_t> parse_initial_memory(const Module& module) {
         std::vector<uint8_t> mem_image;

         for(const DataSegment& data_segment : module.dataSegments) {
            FC_ASSERT(data_segment.baseOffset.type == InitializerExpression::Type::i32_const);
            FC_ASSERT(module.memories.defs.size());
            const U32 base_offset = data_segment.baseOffset.i32;
            const Uptr memory_size = (module.memories.defs[0].type.size.min << IR::numBytesPerPageLog2);
            if(base_offset >= memory_size || base_offset + data_segment.data.size() > memory_size)
               FC_THROW_EXCEPTION(wasm_execution_error, "WASM data segment outside of valid memory range");
            if(base_offset + data_segment.data.size() > mem_image.size())
               mem_image.resize(base_offset + data_segment.data.size(), 0x00);
            memcpy(mem_image.data() + base_offset, data_segment.data.data(), data_segment.data.size());
         }

         return mem_image;
      }

      std::unique_ptr<wasm_instantiated_module_interface>& get_instantiated_module(const digest_type& code_id, const shared_vector<char>& code) {
         auto it = instantiation_cache.find(code_id);
         if(it == instantiation_cache.end()) {
            ilog("START0 ${now}", ("now",fc::time_point::now()));
            IR::Module module;
            try {
               Serialization::MemoryInputStream stream((const U8*)code.data(), code.size());
               WASM::serialize(stream, module);
            } catch(Serialization::FatalSerializationException& e) {
               EOS_ASSERT(false, wasm_serialization_error, e.message.c_str());
            }

            wasm_injections::wasm_binary_injection injector(module);
            injector.inject();

            std::vector<U8> bytes;
            try {
               Serialization::ArrayOutputStream outstream;
               WASM::serialize(outstream, module);
               bytes = outstream.getBytes();
            } catch(Serialization::FatalSerializationException& e) {
               EOS_ASSERT(false, wasm_serialization_error, e.message.c_str());
            }

            it = instantiation_cache.emplace(code_id, runtime_interface->instantiate_module((const char*)bytes.data(), bytes.size(), parse_initial_memory(module))).first;
            ilog("END0 ${now}", ("now",fc::time_point::now()));
         }
         return it->second;
      }

      std::unique_ptr<wasm_runtime_interface> runtime_interface;
      map<digest_type, std::unique_ptr<wasm_instantiated_module_interface>> instantiation_cache;
   };

#define _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
   _REGISTER_WAVM_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
   _REGISTER_BINARYEN_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)

#define _REGISTER_INTRINSIC4(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
   _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, SIG )

#define _REGISTER_INTRINSIC3(CLS, MOD, METHOD, WASM_SIG, NAME)\
   _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, decltype(&CLS::METHOD) )

#define _REGISTER_INTRINSIC2(CLS, MOD, METHOD, WASM_SIG)\
   _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, BOOST_PP_STRINGIZE(METHOD), decltype(&CLS::METHOD) )

#define _REGISTER_INTRINSIC1(CLS, MOD, METHOD)\
   static_assert(false, "Cannot register " BOOST_PP_STRINGIZE(CLS) ":" BOOST_PP_STRINGIZE(METHOD) " without a signature");

#define _REGISTER_INTRINSIC0(CLS, MOD, METHOD)\
   static_assert(false, "Cannot register " BOOST_PP_STRINGIZE(CLS) ":<unknown> without a method name and signature");

#define _UNWRAP_SEQ(...) __VA_ARGS__

#define _EXPAND_ARGS(CLS, MOD, INFO)\
   ( CLS, MOD, _UNWRAP_SEQ INFO )

#define _REGISTER_INTRINSIC(R, CLS, INFO)\
   BOOST_PP_CAT(BOOST_PP_OVERLOAD(_REGISTER_INTRINSIC, _UNWRAP_SEQ INFO) _EXPAND_ARGS(CLS, "env", INFO), BOOST_PP_EMPTY())

#define REGISTER_INTRINSICS(CLS, MEMBERS)\
   BOOST_PP_SEQ_FOR_EACH(_REGISTER_INTRINSIC, CLS, _WRAPPED_SEQ(MEMBERS))

#define _REGISTER_INJECTED_INTRINSIC(R, CLS, INFO)\
   BOOST_PP_CAT(BOOST_PP_OVERLOAD(_REGISTER_INTRINSIC, _UNWRAP_SEQ INFO) _EXPAND_ARGS(CLS, EOSIO_INJECTED_MODULE_NAME, INFO), BOOST_PP_EMPTY())

#define REGISTER_INJECTED_INTRINSICS(CLS, MEMBERS)\
   BOOST_PP_SEQ_FOR_EACH(_REGISTER_INJECTED_INTRINSIC, CLS, _WRAPPED_SEQ(MEMBERS))

} } // eosio::chain
<commit_msg>Forgot debug output<commit_after>#pragma once

#include <eosio/chain/wasm_interface.hpp>
#include <eosio/chain/webassembly/wavm.hpp>
#include <eosio/chain/webassembly/binaryen.hpp>
#include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/wasm_eosio_injection.hpp>

#include "IR/Module.h"
#include "Runtime/Intrinsics.h"
#include "Platform/Platform.h"
#include "WAST/WAST.h"
#include "IR/Validate.h"

using namespace fc;
using namespace eosio::chain::webassembly;
using namespace IR;
using namespace Runtime;

namespace eosio { namespace chain {

   struct wasm_interface_impl {
      wasm_interface_impl(wasm_interface::vm_type vm) {
         if(vm == wasm_interface::vm_type::wavm)
            runtime_interface = std::make_unique<webassembly::wavm::wavm_runtime>();
         else if(vm == wasm_interface::vm_type::binaryen)
            runtime_interface = std::make_unique<webassembly::binaryen::binaryen_runtime>();
         else
            FC_THROW("wasm_interface_impl fall through");
      }

      std::vector<uint8_t> parse_initial_memory(const Module& module) {
         std::vector<uint8_t> mem_image;

         for(const DataSegment& data_segment : module.dataSegments) {
            FC_ASSERT(data_segment.baseOffset.type == InitializerExpression::Type::i32_const);
            FC_ASSERT(module.memories.defs.size());
            const U32 base_offset = data_segment.baseOffset.i32;
            const Uptr memory_size = (module.memories.defs[0].type.size.min << IR::numBytesPerPageLog2);
            if(base_offset >= memory_size || base_offset + data_segment.data.size() > memory_size)
               FC_THROW_EXCEPTION(wasm_execution_error, "WASM data segment outside of valid memory range");
            if(base_offset + data_segment.data.size() > mem_image.size())
               mem_image.resize(base_offset + data_segment.data.size(), 0x00);
            memcpy(mem_image.data() + base_offset, data_segment.data.data(), data_segment.data.size());
         }

         return mem_image;
      }

      std::unique_ptr<wasm_instantiated_module_interface>& get_instantiated_module(const digest_type& code_id, const shared_vector<char>& code) {
         auto it = instantiation_cache.find(code_id);
         if(it == instantiation_cache.end()) {
            IR::Module module;
            try {
               Serialization::MemoryInputStream stream((const U8*)code.data(), code.size());
               WASM::serialize(stream, module);
            } catch(Serialization::FatalSerializationException& e) {
               EOS_ASSERT(false, wasm_serialization_error, e.message.c_str());
            }

            wasm_injections::wasm_binary_injection injector(module);
            injector.inject();

            std::vector<U8> bytes;
            try {
               Serialization::ArrayOutputStream outstream;
               WASM::serialize(outstream, module);
               bytes = outstream.getBytes();
            } catch(Serialization::FatalSerializationException& e) {
               EOS_ASSERT(false, wasm_serialization_error, e.message.c_str());
            }

            it = instantiation_cache.emplace(code_id, runtime_interface->instantiate_module((const char*)bytes.data(), bytes.size(), parse_initial_memory(module))).first;
         }
         return it->second;
      }

      std::unique_ptr<wasm_runtime_interface> runtime_interface;
      map<digest_type, std::unique_ptr<wasm_instantiated_module_interface>> instantiation_cache;
   };

#define _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
   _REGISTER_WAVM_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
   _REGISTER_BINARYEN_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)

#define _REGISTER_INTRINSIC4(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
   _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, SIG )

#define _REGISTER_INTRINSIC3(CLS, MOD, METHOD, WASM_SIG, NAME)\
   _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, decltype(&CLS::METHOD) )

#define _REGISTER_INTRINSIC2(CLS, MOD, METHOD, WASM_SIG)\
   _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, BOOST_PP_STRINGIZE(METHOD), decltype(&CLS::METHOD) )

#define _REGISTER_INTRINSIC1(CLS, MOD, METHOD)\
   static_assert(false, "Cannot register " BOOST_PP_STRINGIZE(CLS) ":" BOOST_PP_STRINGIZE(METHOD) " without a signature");

#define _REGISTER_INTRINSIC0(CLS, MOD, METHOD)\
   static_assert(false, "Cannot register " BOOST_PP_STRINGIZE(CLS) ":<unknown> without a method name and signature");

#define _UNWRAP_SEQ(...) __VA_ARGS__

#define _EXPAND_ARGS(CLS, MOD, INFO)\
   ( CLS, MOD, _UNWRAP_SEQ INFO )

#define _REGISTER_INTRINSIC(R, CLS, INFO)\
   BOOST_PP_CAT(BOOST_PP_OVERLOAD(_REGISTER_INTRINSIC, _UNWRAP_SEQ INFO) _EXPAND_ARGS(CLS, "env", INFO), BOOST_PP_EMPTY())

#define REGISTER_INTRINSICS(CLS, MEMBERS)\
   BOOST_PP_SEQ_FOR_EACH(_REGISTER_INTRINSIC, CLS, _WRAPPED_SEQ(MEMBERS))

#define _REGISTER_INJECTED_INTRINSIC(R, CLS, INFO)\
   BOOST_PP_CAT(BOOST_PP_OVERLOAD(_REGISTER_INTRINSIC, _UNWRAP_SEQ INFO) _EXPAND_ARGS(CLS, EOSIO_INJECTED_MODULE_NAME, INFO), BOOST_PP_EMPTY())

#define REGISTER_INJECTED_INTRINSICS(CLS, MEMBERS)\
   BOOST_PP_SEQ_FOR_EACH(_REGISTER_INJECTED_INTRINSIC, CLS, _WRAPPED_SEQ(MEMBERS))

} } // eosio::chain
<|endoftext|>


<commit_before>#include <iostream>

#include "occa.hpp"

int main(int argc, char **argv){
  int entries = 5;

  //---[ Init CUDA ]------------------
  int cuDeviceID;
  void *cu_a, *cu_b, *cu_ab;

  cudaMalloc(&cu_a , entries*sizeof(float));
  cudaMalloc(&cu_b , entries*sizeof(float));
  cudaMalloc(&cu_ab, entries*sizeof(float));

  //  ---[ Get CUDA Info ]----
  CUdevice cuDevice;
  CUcontext cuContext;

  cuDeviceGet(&cuDevice, cuDeviceID);
  cuCtxGetCurrent(&cuContext);
  //  ========================
  //====================================

  float *a  = new float[entries];
  float *b  = new float[entries];
  float *ab = new float[entries];

  occa::device device = occa::cuda::wrapDevice(cuDevice, cuContext);
  occa::kernel addVectors;
  occa::memory o_a, o_b, o_ab;

  for(int i = 0; i < entries; ++i){
    a[i]  = i;
    b[i]  = 1 - i;
    ab[i] = 0;
  }

  o_a  = device.wrapMemory(&cu_a , entries*sizeof(float));
  o_b  = device.wrapMemory(&cu_b , entries*sizeof(float));
  o_ab = device.wrapMemory(&cu_ab, entries*sizeof(float));

  addVectors = device.buildKernelFromSource("addVectors.occa",
                                            "addVectors");

  int dims = 1;
  int itemsPerGroup(2);
  int groups((entries + itemsPerGroup - 1)/itemsPerGroup);

  addVectors.setWorkingDims(dims, itemsPerGroup, groups);

  o_a.copyFrom(a);
  o_b.copyFrom(b);

  occa::initTimer(device);

  occa::tic("addVectors");

  addVectors(entries, o_a, o_b, o_ab);

  double elapsedTime = occa::toc("addVectors", addVectors);

  o_ab.copyTo(ab);

  std::cout << "Elapsed time = " << elapsedTime << " s" << std::endl;

  occa::printTimer();

  for(int i = 0; i < 5; ++i)
    std::cout << i << ": " << ab[i] << '\n';

  addVectors.free();
  o_a.free();
  o_b.free();
  o_ab.free();

  delete [] a;
  delete [] b;
  delete [] ab;

  return 0;
}
<commit_msg>[Example] Updated CUDA wrapping example (still need to test)<commit_after>#include <iostream>

#include "occa.hpp"

int main(int argc, char **argv){
  int entries = 5;

  //---[ Init CUDA ]------------------
  int cuDeviceID;
  cudaStream_t cuStream;
  void *cu_a, *cu_b, *cu_ab;

  // Default: cuStream = 0
  cudaStreamCreate(&customStream);

  cudaMalloc(&cu_a , entries*sizeof(float));
  cudaMalloc(&cu_b , entries*sizeof(float));
  cudaMalloc(&cu_ab, entries*sizeof(float));

  //  ---[ Get CUDA Info ]----
  CUdevice cuDevice;
  CUcontext cuContext;

  cuDeviceGet(&cuDevice, cuDeviceID);
  cuCtxGetCurrent(&cuContext);
  //  ========================
  //====================================

  float *a  = new float[entries];
  float *b  = new float[entries];
  float *ab = new float[entries];

  occa::device device = occa::cuda::wrapDevice(cuDevice, cuContext);

  occa::stream stream = device.wrapStream(&cuStream);
  device.setStream(stream);

  occa::kernel addVectors;
  occa::memory o_a, o_b, o_ab;

  for(int i = 0; i < entries; ++i){
    a[i]  = i;
    b[i]  = 1 - i;
    ab[i] = 0;
  }

  o_a  = device.wrapMemory(&cu_a , entries*sizeof(float));
  o_b  = device.wrapMemory(&cu_b , entries*sizeof(float));
  o_ab = device.wrapMemory(&cu_ab, entries*sizeof(float));

  addVectors = device.buildKernelFromSource("addVectors.occa",
                                            "addVectors");

  int dims = 1;
  int itemsPerGroup(2);
  int groups((entries + itemsPerGroup - 1)/itemsPerGroup);

  addVectors.setWorkingDims(dims, itemsPerGroup, groups);

  o_a.copyFrom(a);
  o_b.copyFrom(b);

  occa::initTimer(device);

  occa::tic("addVectors");

  addVectors(entries, o_a, o_b, o_ab);

  double elapsedTime = occa::toc("addVectors", addVectors);

  o_ab.copyTo(ab);

  std::cout << "Elapsed time = " << elapsedTime << " s" << std::endl;

  occa::printTimer();

  for(int i = 0; i < 5; ++i)
    std::cout << i << ": " << ab[i] << '\n';

  addVectors.free();
  o_a.free();
  o_b.free();
  o_ab.free();

  delete [] a;
  delete [] b;
  delete [] ab;

  return 0;
}
<|endoftext|>


<commit_before>//   Copyright 2015 Patrick Putnam
//
//   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.
#ifndef FITNESS_GENERATOR_HPP_
#define FITNESS_GENERATOR_HPP_

#include <boost/property_tree/ptree.hpp>
#include <iterator>
#include "clotho/genetics/normal_fitness_metric.hpp"

class normal_fitness_generator {
public:
    typedef normal_fitness_metric   result_type;

    normal_fitness_generator( boost::property_tree::ptree & config ) :
        m_mu(1.) {
        parseConfig( config );
    }

    template < class Iter >
    result_type operator()( Iter first, Iter last ) {
        // theoretical standard deviation:
        // sqrt( 2 * N * mu), where
        //  N - is the haploid sequence count
        //  mu - mutation rate per sequence
        // distance(,) - number of individuals in population (N_p) => N = 2 * (N_p); hence:  4.0 * N_p
        double n = 4.0 * (double)std::distance(first, last);

        n *= m_mu;
        n = sqrt(n);    // theoretical standard deviation

        return result_type( 0., n );
    }

protected:

    void parseConfig( boost::property_tree::ptree & config ) {
        std::ostringstream oss;
        oss << CONFIG_BLOCK_K << "." << MUT_BLOCK_K << "." << RATE_PER_REGION_K;
        if( config.get_child_optional( oss.str() ) != boost::none ) {
            m_mu = config.get< double >( oss.str(), 1. );
        }
    }

    double m_mu;
};

#include "clotho/genetics/quadratic_fitness_metric.hpp"

extern const string FITNESS_BLOCK_K;
extern const string QUADRATIC_SCALE_K;

class quadratic_fitness_generator {
public:
    typedef quadratic_fitness_metric   result_type;

    quadratic_fitness_generator( boost::property_tree::ptree & config ) :
        m_scale(1.)
        , m_mu( 1. ) {
        parseConfig( config );
    }

    template < class Iter >
    result_type operator()( Iter first, Iter last ) {
        // theoretical standard deviation:
        // sqrt( 2 * N * mu), where
        //  N - is the haploid sequence count
        //  mu - mutation rate per sequence
        // distance(,) - number of individuals in population (N_p) => N = 2 * (N_p); hence:  4.0 * N_p
        double res = 4.0 * (double)std::distance( first, last );

        res *= m_mu;
        res = sqrt( res );  // theoretical standard deviation

        return result_type( m_scale * res );
    }

protected:

    void parseConfig( boost::property_tree::ptree & config ) {
        std::ostringstream oss;
        oss << CONFIG_BLOCK_K << "." << FITNESS_BLOCK_K << "." << QUADRATIC_SCALE_K;
        if( config.get_child_optional( oss.str() ) == boost::none ) {
            config.put( oss.str(), m_scale );
        } else {
            m_scale = config.get< double >( oss.str(), 1. );

            assert( m_scale > 0.0 );
        }

        oss.str("");
        oss.clear();
        oss << CONFIG_BLOCK_K << "." << MUT_BLOCK_K << "." << RATE_PER_REGION_K;
        if( config.get_child_optional( oss.str() ) != boost::none ) {
            m_mu = config.get< double >( oss.str(), 1. );
        }
    }

    double m_scale, m_mu;
};

#include "clotho/genetics/constant_fitness_metric.hpp"

extern const string CONSTANT_K;

class constant_fitness_generator {
public:
    typedef constant_fitness_metric   result_type;

    constant_fitness_generator( boost::property_tree::ptree & config ) :
        m_val( 1. ) {
        parseConfig( config );
    }

    template < class Iter >
    result_type operator()( Iter first, Iter last ) {
        return result_type( m_val );
    }
protected:

    void parseConfig( boost::property_tree::ptree & config ) {
        std::ostringstream oss;
        oss << CONFIG_BLOCK_K << "." << FITNESS_BLOCK_K << "." << CONSTANT_K;
        if( config.get_child_optional( oss.str() ) == boost::none ) {
            config.put( oss.str(), m_val );
        } else {
            m_val = config.get< double >( oss.str(), 1. );
        }

    }

    double m_val;
};

#endif  // FITNESS_GENERATOR_HPP_
<commit_msg>Deprecated<commit_after><|endoftext|>