<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativegraphicsgeomap_p.h"

#include "qdeclarativecoordinate_p.h"
#include "qdeclarativegeoserviceprovider_p.h"

#include <qgeoserviceprovider.h>
#include <qgeomappingmanager.h>
#include <qgeomapdata.h>
#include <qgeomapobject.h>

QTM_BEGIN_NAMESPACE

QDeclarativeGraphicsGeoMap::QDeclarativeGraphicsGeoMap(QDeclarativeItem *parent)
    : QDeclarativeItem(parent),
    serviceProvider_(0),
    mapData_(0)
{
    setFlag(QGraphicsItem::ItemHasNoContents, false);
    center_ = new QDeclarativeCoordinate(this);
    center_->setCoordinate(QGeoCoordinate(-27.0, 153.0));
    mapType_ = QDeclarativeGraphicsGeoMap::StreetMap;
    zoomLevel_ = 8;
    size_ = QSizeF(100.0, 100.0);

}

QDeclarativeGraphicsGeoMap::~QDeclarativeGraphicsGeoMap()
{
    qDeleteAll(objects_);

    if (mapData_)
        delete mapData_;

    if (serviceProvider_)
        delete serviceProvider_;
}

void QDeclarativeGraphicsGeoMap::paint(QPainter *painter,
                                       const QStyleOptionGraphicsItem *option,
                                       QWidget * /*widget*/)
{
    if (mapData_) {
        mapData_->paint(painter, option);
    }
}

void QDeclarativeGraphicsGeoMap::geometryChanged(const QRectF &newGeometry,
                                                 const QRectF & /*oldGeometry*/)
{
    setSize(newGeometry.size());
}

// this is write once
void QDeclarativeGraphicsGeoMap::setPlugin(QDeclarativeGeoServiceProvider *plugin)
{
    if (plugin_)
        return;

    plugin_ = plugin;

    emit pluginChanged(plugin_);

    serviceProvider_ = new QGeoServiceProvider(plugin_->name(),
                                               plugin_->parameterMap());

    // check for error

    mappingManager_ = serviceProvider_->mappingManager();

    // check for error

    mapData_ = mappingManager_->createMapData();
    mapData_->init();
    //mapData_->setParentItem(this);

    // setters
    mapData_->setWindowSize(size_);
    mapData_->setZoomLevel(zoomLevel_);
    mapData_->setCenter(center_->coordinate());
    mapData_->setMapType(QGraphicsGeoMap::MapType(mapType_));
    mapData_->setConnectivityMode(QGraphicsGeoMap::ConnectivityMode(connectivityMode_));

    for (int i = 0; i < objects_.size(); ++i)
        mapData_->addMapObject(objects_.at(i));
    objects_.clear();

    // setup signals

    connect(mapData_,
            SIGNAL(updateMapDisplay(QRectF)),
            this,
            SLOT(updateMapDisplay(QRectF)));

    connect(mapData_,
            SIGNAL(centerChanged(QGeoCoordinate)),
            this,
            SLOT(internalCenterChanged(QGeoCoordinate)));

    connect(mapData_,
            SIGNAL(mapTypeChanged(QGraphicsGeoMap::MapType)),
            this,
            SLOT(internalMapTypeChanged(QGraphicsGeoMap::MapType)));

    connect(mapData_,
            SIGNAL(connectivityModeChanged(QGraphicsGeoMap::ConnectivityMode)),
            this,
            SLOT(internalConnectivityModeChanged(QGraphicsGeoMap::ConnectivityMode)));

    connect(mapData_,
            SIGNAL(windowSizeChanged(QSizeF)),
            this,
            SIGNAL(sizeChanged(QSizeF)));

    connect(mapData_,
            SIGNAL(zoomLevelChanged(qreal)),
            this,
            SIGNAL(zoomLevelChanged(qreal)));
}

void QDeclarativeGraphicsGeoMap::updateMapDisplay(const QRectF &target)
{
    update(target);
}

QDeclarativeGeoServiceProvider* QDeclarativeGraphicsGeoMap::plugin() const
{
    return plugin_;
}

qreal QDeclarativeGraphicsGeoMap::minimumZoomLevel() const
{
    if (mappingManager_)
        return mappingManager_->minimumZoomLevel();
    else
        return -1.0;
}

qreal QDeclarativeGraphicsGeoMap::maximumZoomLevel() const
{
    if (mappingManager_)
        return mappingManager_->maximumZoomLevel();
    else
        return -1.0;
}

// TODO make these more QML like
//QList<MapType> QDeclarativeGraphicsGeoMap::supportedMapTypes() const;
//QList<ConnectivityMode> QDeclarativeGraphicsGeoMap::supportedConnectivityModes() const;

void QDeclarativeGraphicsGeoMap::setSize(const QSizeF &size)
{
    if (mapData_) {
        setWidth(size.width());
        setHeight(size.height());
        mapData_->setWindowSize(size);
    } else {
        if (size_ == size)
            return;

        size_ = size;

        emit sizeChanged(size_);
    }

}

QSizeF QDeclarativeGraphicsGeoMap::size() const
{
    if (mapData_)
        return mapData_->windowSize();
    else
        return size_;
}

void QDeclarativeGraphicsGeoMap::setZoomLevel(qreal zoomLevel)
{
    if (mapData_) {
        mapData_->setZoomLevel(zoomLevel);
    } else {
        if (zoomLevel_ == zoomLevel)
            return;

        zoomLevel_ = zoomLevel;

        emit zoomLevelChanged(zoomLevel_);
    }
}

qreal QDeclarativeGraphicsGeoMap::zoomLevel() const
{
    if (mapData_) {
        return mapData_->zoomLevel();
    } else {
        return zoomLevel_;
    }
}

void QDeclarativeGraphicsGeoMap::setCenter(const QDeclarativeCoordinate *center)
{
    if (mapData_) {
        mapData_->setCenter(center->coordinate());
    } else {
        if (center_->coordinate() == center->coordinate())
            return;

        center_->setCoordinate(center->coordinate());

        // TODO emit signal
    }
}

QDeclarativeCoordinate* QDeclarativeGraphicsGeoMap::center() const
{
    if (mapData_)
        center_->setCoordinate(mapData_->center());
    return center_;
}

void QDeclarativeGraphicsGeoMap::setMapType(QDeclarativeGraphicsGeoMap::MapType mapType)
{
    if (mapData_) {
        mapData_->setMapType(QGraphicsGeoMap::MapType(mapType));
    } else {
        if (mapType_ == mapType)
            return;

        mapType_ = mapType;

        emit mapTypeChanged(mapType_);
    }
}

QDeclarativeGraphicsGeoMap::MapType QDeclarativeGraphicsGeoMap::mapType() const
{
    if (mapData_) {
        return QDeclarativeGraphicsGeoMap::MapType(mapData_->mapType());
    } else {
        return mapType_;
    }
}

void QDeclarativeGraphicsGeoMap::setConnectivityMode(QDeclarativeGraphicsGeoMap::ConnectivityMode connectivityMode)
{
    if (mapData_) {
        mapData_->setConnectivityMode(QGraphicsGeoMap::ConnectivityMode(connectivityMode));
    } else {
        if (connectivityMode_ == connectivityMode)
            return;

        connectivityMode_ = connectivityMode;

        emit connectivityModeChanged(connectivityMode_);
    }
}

QDeclarativeGraphicsGeoMap::ConnectivityMode QDeclarativeGraphicsGeoMap::connectivityMode() const
{
    if (mapData_)
        return QDeclarativeGraphicsGeoMap::ConnectivityMode(mapData_->connectivityMode());
    else
        return connectivityMode_;
}

QDeclarativeListProperty<QGeoMapObject> QDeclarativeGraphicsGeoMap::objects()
{
    return QDeclarativeListProperty<QGeoMapObject>(this,
            0,
            object_append,
            object_count,
            object_at,
            object_clear);
}

void QDeclarativeGraphicsGeoMap::object_append(QDeclarativeListProperty<QGeoMapObject> *prop, QGeoMapObject *mapObject)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        map->mapData_->addMapObject(mapObject);
    else
        map->objects_.append(mapObject);
}

int QDeclarativeGraphicsGeoMap::object_count(QDeclarativeListProperty<QGeoMapObject> *prop)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        return map->mapData_->mapObjects().size();
    else
        return map->objects_.size();
}

QGeoMapObject *QDeclarativeGraphicsGeoMap::object_at(QDeclarativeListProperty<QGeoMapObject> *prop, int index)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        return map->mapData_->mapObjects().at(index);
    else
        return map->objects_.at(index);
}

void QDeclarativeGraphicsGeoMap::object_clear(QDeclarativeListProperty<QGeoMapObject> *prop)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        map->mapData_->clearMapObjects();
    else
        map->objects_.clear();
}

QDeclarativeCoordinate* QDeclarativeGraphicsGeoMap::toCoordinate(QPointF screenPosition) const
{
    QGeoCoordinate coordinate;

    if (mapData_)
        coordinate = mapData_->screenPositionToCoordinate(screenPosition);

    return new QDeclarativeCoordinate(coordinate,
                                      const_cast<QDeclarativeGraphicsGeoMap *>(this));
}

QPointF QDeclarativeGraphicsGeoMap::toScreenPosition(QDeclarativeCoordinate* coordinate) const
{
    QPointF point;

    if (mapData_)
        point = mapData_->coordinateToScreenPosition(coordinate->coordinate());

    return point;
}

void QDeclarativeGraphicsGeoMap::pan(int dx, int dy)
{
    if (mapData_) {
        mapData_->pan(dx, dy);
        update();
    }
}

void QDeclarativeGraphicsGeoMap::internalCenterChanged(const QGeoCoordinate &coordinate)
{
    emit declarativeCenterChanged(new QDeclarativeCoordinate(coordinate, this));
}

void QDeclarativeGraphicsGeoMap::internalMapTypeChanged(QGraphicsGeoMap::MapType mapType)
{
    emit mapTypeChanged(QDeclarativeGraphicsGeoMap::MapType(mapType));
}

void QDeclarativeGraphicsGeoMap::internalConnectivityModeChanged(QGraphicsGeoMap::ConnectivityMode connectivityMode)
{
    emit connectivityModeChanged(QDeclarativeGraphicsGeoMap::ConnectivityMode(connectivityMode));
}

#include "moc_qdeclarativegraphicsgeomap_p.cpp"

QTM_END_NAMESPACE

<commit_msg>Fixed the QML map so that it always emits center notification signals.<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativegraphicsgeomap_p.h"

#include "qdeclarativecoordinate_p.h"
#include "qdeclarativegeoserviceprovider_p.h"

#include <qgeoserviceprovider.h>
#include <qgeomappingmanager.h>
#include <qgeomapdata.h>
#include <qgeomapobject.h>

QTM_BEGIN_NAMESPACE

QDeclarativeGraphicsGeoMap::QDeclarativeGraphicsGeoMap(QDeclarativeItem *parent)
    : QDeclarativeItem(parent),
    serviceProvider_(0),
    mapData_(0)
{
    setFlag(QGraphicsItem::ItemHasNoContents, false);
    center_ = new QDeclarativeCoordinate(this);
    center_->setCoordinate(QGeoCoordinate(-27.0, 153.0));
    mapType_ = QDeclarativeGraphicsGeoMap::StreetMap;
    zoomLevel_ = 8;
    size_ = QSizeF(100.0, 100.0);

}

QDeclarativeGraphicsGeoMap::~QDeclarativeGraphicsGeoMap()
{
    qDeleteAll(objects_);

    if (mapData_)
        delete mapData_;

    if (serviceProvider_)
        delete serviceProvider_;
}

void QDeclarativeGraphicsGeoMap::paint(QPainter *painter,
                                       const QStyleOptionGraphicsItem *option,
                                       QWidget * /*widget*/)
{
    if (mapData_) {
        mapData_->paint(painter, option);
    }
}

void QDeclarativeGraphicsGeoMap::geometryChanged(const QRectF &newGeometry,
                                                 const QRectF & /*oldGeometry*/)
{
    setSize(newGeometry.size());
}

// this is write once
void QDeclarativeGraphicsGeoMap::setPlugin(QDeclarativeGeoServiceProvider *plugin)
{
    if (plugin_)
        return;

    plugin_ = plugin;

    emit pluginChanged(plugin_);

    serviceProvider_ = new QGeoServiceProvider(plugin_->name(),
                                               plugin_->parameterMap());

    // check for error

    mappingManager_ = serviceProvider_->mappingManager();

    // check for error

    mapData_ = mappingManager_->createMapData();
    mapData_->init();
    //mapData_->setParentItem(this);

    // setters
    mapData_->setWindowSize(size_);
    mapData_->setZoomLevel(zoomLevel_);
    mapData_->setCenter(center_->coordinate());
    mapData_->setMapType(QGraphicsGeoMap::MapType(mapType_));
    mapData_->setConnectivityMode(QGraphicsGeoMap::ConnectivityMode(connectivityMode_));

    for (int i = 0; i < objects_.size(); ++i)
        mapData_->addMapObject(objects_.at(i));
    objects_.clear();

    // setup signals

    connect(mapData_,
            SIGNAL(updateMapDisplay(QRectF)),
            this,
            SLOT(updateMapDisplay(QRectF)));

    connect(mapData_,
            SIGNAL(centerChanged(QGeoCoordinate)),
            this,
            SLOT(internalCenterChanged(QGeoCoordinate)));

    connect(mapData_,
            SIGNAL(mapTypeChanged(QGraphicsGeoMap::MapType)),
            this,
            SLOT(internalMapTypeChanged(QGraphicsGeoMap::MapType)));

    connect(mapData_,
            SIGNAL(connectivityModeChanged(QGraphicsGeoMap::ConnectivityMode)),
            this,
            SLOT(internalConnectivityModeChanged(QGraphicsGeoMap::ConnectivityMode)));

    connect(mapData_,
            SIGNAL(windowSizeChanged(QSizeF)),
            this,
            SIGNAL(sizeChanged(QSizeF)));

    connect(mapData_,
            SIGNAL(zoomLevelChanged(qreal)),
            this,
            SIGNAL(zoomLevelChanged(qreal)));
}

void QDeclarativeGraphicsGeoMap::updateMapDisplay(const QRectF &target)
{
    update(target);
}

QDeclarativeGeoServiceProvider* QDeclarativeGraphicsGeoMap::plugin() const
{
    return plugin_;
}

qreal QDeclarativeGraphicsGeoMap::minimumZoomLevel() const
{
    if (mappingManager_)
        return mappingManager_->minimumZoomLevel();
    else
        return -1.0;
}

qreal QDeclarativeGraphicsGeoMap::maximumZoomLevel() const
{
    if (mappingManager_)
        return mappingManager_->maximumZoomLevel();
    else
        return -1.0;
}

// TODO make these more QML like
//QList<MapType> QDeclarativeGraphicsGeoMap::supportedMapTypes() const;
//QList<ConnectivityMode> QDeclarativeGraphicsGeoMap::supportedConnectivityModes() const;

void QDeclarativeGraphicsGeoMap::setSize(const QSizeF &size)
{
    if (mapData_) {
        setWidth(size.width());
        setHeight(size.height());
        mapData_->setWindowSize(size);
    } else {
        if (size_ == size)
            return;

        size_ = size;

        emit sizeChanged(size_);
    }

}

QSizeF QDeclarativeGraphicsGeoMap::size() const
{
    if (mapData_)
        return mapData_->windowSize();
    else
        return size_;
}

void QDeclarativeGraphicsGeoMap::setZoomLevel(qreal zoomLevel)
{
    if (mapData_) {
        mapData_->setZoomLevel(zoomLevel);
    } else {
        if (zoomLevel_ == zoomLevel)
            return;

        zoomLevel_ = zoomLevel;

        emit zoomLevelChanged(zoomLevel_);
    }
}

qreal QDeclarativeGraphicsGeoMap::zoomLevel() const
{
    if (mapData_) {
        return mapData_->zoomLevel();
    } else {
        return zoomLevel_;
    }
}

void QDeclarativeGraphicsGeoMap::setCenter(const QDeclarativeCoordinate *center)
{
    if (mapData_) {
        mapData_->setCenter(center->coordinate());
    } else {
        if (center_->coordinate() == center->coordinate())
            return;

        center_->setCoordinate(center->coordinate());

        emit declarativeCenterChanged(center_);
    }
}

QDeclarativeCoordinate* QDeclarativeGraphicsGeoMap::center() const
{
    if (mapData_)
        center_->setCoordinate(mapData_->center());
    return center_;
}

void QDeclarativeGraphicsGeoMap::setMapType(QDeclarativeGraphicsGeoMap::MapType mapType)
{
    if (mapData_) {
        mapData_->setMapType(QGraphicsGeoMap::MapType(mapType));
    } else {
        if (mapType_ == mapType)
            return;

        mapType_ = mapType;

        emit mapTypeChanged(mapType_);
    }
}

QDeclarativeGraphicsGeoMap::MapType QDeclarativeGraphicsGeoMap::mapType() const
{
    if (mapData_) {
        return QDeclarativeGraphicsGeoMap::MapType(mapData_->mapType());
    } else {
        return mapType_;
    }
}

void QDeclarativeGraphicsGeoMap::setConnectivityMode(QDeclarativeGraphicsGeoMap::ConnectivityMode connectivityMode)
{
    if (mapData_) {
        mapData_->setConnectivityMode(QGraphicsGeoMap::ConnectivityMode(connectivityMode));
    } else {
        if (connectivityMode_ == connectivityMode)
            return;

        connectivityMode_ = connectivityMode;

        emit connectivityModeChanged(connectivityMode_);
    }
}

QDeclarativeGraphicsGeoMap::ConnectivityMode QDeclarativeGraphicsGeoMap::connectivityMode() const
{
    if (mapData_)
        return QDeclarativeGraphicsGeoMap::ConnectivityMode(mapData_->connectivityMode());
    else
        return connectivityMode_;
}

QDeclarativeListProperty<QGeoMapObject> QDeclarativeGraphicsGeoMap::objects()
{
    return QDeclarativeListProperty<QGeoMapObject>(this,
            0,
            object_append,
            object_count,
            object_at,
            object_clear);
}

void QDeclarativeGraphicsGeoMap::object_append(QDeclarativeListProperty<QGeoMapObject> *prop, QGeoMapObject *mapObject)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        map->mapData_->addMapObject(mapObject);
    else
        map->objects_.append(mapObject);
}

int QDeclarativeGraphicsGeoMap::object_count(QDeclarativeListProperty<QGeoMapObject> *prop)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        return map->mapData_->mapObjects().size();
    else
        return map->objects_.size();
}

QGeoMapObject *QDeclarativeGraphicsGeoMap::object_at(QDeclarativeListProperty<QGeoMapObject> *prop, int index)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        return map->mapData_->mapObjects().at(index);
    else
        return map->objects_.at(index);
}

void QDeclarativeGraphicsGeoMap::object_clear(QDeclarativeListProperty<QGeoMapObject> *prop)
{
    QDeclarativeGraphicsGeoMap *map = static_cast<QDeclarativeGraphicsGeoMap*>(prop->object);

    if (map->mapData_)
        map->mapData_->clearMapObjects();
    else
        map->objects_.clear();
}

QDeclarativeCoordinate* QDeclarativeGraphicsGeoMap::toCoordinate(QPointF screenPosition) const
{
    QGeoCoordinate coordinate;

    if (mapData_)
        coordinate = mapData_->screenPositionToCoordinate(screenPosition);

    return new QDeclarativeCoordinate(coordinate,
                                      const_cast<QDeclarativeGraphicsGeoMap *>(this));
}

QPointF QDeclarativeGraphicsGeoMap::toScreenPosition(QDeclarativeCoordinate* coordinate) const
{
    QPointF point;

    if (mapData_)
        point = mapData_->coordinateToScreenPosition(coordinate->coordinate());

    return point;
}

void QDeclarativeGraphicsGeoMap::pan(int dx, int dy)
{
    if (mapData_) {
        mapData_->pan(dx, dy);
        update();
    }
}

void QDeclarativeGraphicsGeoMap::internalCenterChanged(const QGeoCoordinate &coordinate)
{
    emit declarativeCenterChanged(new QDeclarativeCoordinate(coordinate, this));
}

void QDeclarativeGraphicsGeoMap::internalMapTypeChanged(QGraphicsGeoMap::MapType mapType)
{
    emit mapTypeChanged(QDeclarativeGraphicsGeoMap::MapType(mapType));
}

void QDeclarativeGraphicsGeoMap::internalConnectivityModeChanged(QGraphicsGeoMap::ConnectivityMode connectivityMode)
{
    emit connectivityModeChanged(QDeclarativeGraphicsGeoMap::ConnectivityMode(connectivityMode));
}

#include "moc_qdeclarativegraphicsgeomap_p.cpp"

QTM_END_NAMESPACE

<|endoftext|>


<commit_before>#include "nodes/SANode/SANode.hpp"
#include "core/Locus.hpp"
#include <string>
#include <sstream>
#include <iostream>
#include <random>
#include <cmath>

using namespace std;

SANode::SANode(
	int populationSize,
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	populationSize,
	objectives,
	populationToString,
	conditions,
	name
) {
	init(schedule, maximize);
}

SANode::SANode(
	int populationSize,
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	int accelerationFactor,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	populationSize,
	objectives,
	populationToString,
	conditions,
	name,
	accelerationFactor
) {
	init(schedule, maximize);
}

SANode::SANode(
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	1,
	objectives,
	populationToString,
	conditions,
	name
) {
	init(schedule, maximize);
}

SANode::SANode(
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	int accelerationFactor,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	1,
	objectives,
	populationToString,
	conditions,
	name,
	accelerationFactor
) {
	init(schedule, maximize);
}

void SANode::init(bool maximize, TemperatureSchedule * schedule) {
	this->maximize = maximize;
	this->schedule = schedule;
}

vector<Genome*> SANode::getNextPopulation() {
	vector<Genome*> newPopulation;

	for (int i = 0; i < this->populationSize(); i++) {
		newPopulation.push_back(getNeighbour(this->population[i]));
	}

	return newPopulation;
}

int SANode::compareNeighbourliness(Genome * base, Genome * target) {
	return base->difference(target);
}

vector<Genome*> SANode::getAllNeighbours(Genome * target) {
	vector<Genome*> neighbours;
	vector<Locus*> loci = target->getLoci();

	for (int i = 0; i < target->genomeLength(); i++) {
		if (loci[i]->isConstructive()) {
			Genome * nearestKnownNeighbour;
			int top = loci[i]->topIndex();
			int lowestDiff = 0;

			for (int k = 0; k <= top; k++) {

			}
		} else {
			// For simple locus types, just increment/decrement
			// and be done with it
			vector<int> rawGenes = target->getGenome();
			if (!loci[i]->outOfRange(rawGenes[i]+1)) {
				rawGenes[i]++;
				neighbours.push_back(
					new Genome(rawGenes, loci)
				);
				rawGenes[i]--;
			}

			if (!loci[i]->outOfRange(rawGenes[i]-1)) {
				rawGenes[i]--;
				neighbours.push_back(
					new Genome(rawGenes, loci)
				);
			}
		}
	}

	return neighbours;
}

Genome * SANode::getNeighbour(Genome * target) {

}

// Oh God, why did I write it like this?
Individual * SimulatedAnnealer::getNeighbour(Individual * target) {
	int genomeLength = target->getGenomeLength();
	Individual ** neighbours = (Individual**)malloc(
		sizeof(Individual*)*genomeLength
	);
	Individual * temp;
	Genome * tempGenome;

	Genome * baseGenome = target->getGenome();
	GeneNode ** nodes = baseGenome->getGeneNodes();
	int * genes = baseGenome->getGenome();
	int diff;

	for (int i = 0; i < genomeLength; i++) {
		int lowestDiff = 0;
		Individual * nearestKnownNeighbour = NULL;

		// Since we don't know where our nearest neighbour is in a
		// population of components, we have to cycle through them all
		int numAlleles = nodes[i]->getPopulationSize();
		for (int k = 0; k < numAlleles; k++) {
			if (genes[i] == k) {
				if (k < numAlleles - 1) {
					k++;
				} else {
					break;
				}
			}

			int * tempGenes = (int*)malloc(
				sizeof(int)*genomeLength
			);

			for (int c = 0; c < genomeLength; c++) {
				tempGenes[c] = genes[c]; // Reset
			}

			tempGenes[i] = k;

			tempGenome = new Genome(
				tempGenes,
				genomeLength,
				nodes
			);

			temp = target->copyWithNewGenome(tempGenome);
			delete(tempGenome);
			free(tempGenes);
			diff = compareNeighbourliness(target, temp);

			if ((diff < lowestDiff && diff > 0) || lowestDiff == 0) {
				delete(nearestKnownNeighbour);
				nearestKnownNeighbour = temp;
				lowestDiff = diff;
			} else {
				delete(temp);
			}
		}

		if (lowestDiff == 0) {
			// The lowest diff being zero means that we have no
			// neighbours (i.e. all the available choices result
			// in no change)
			neighbours[i] = NULL;
		} else {
			neighbours[i] = nearestKnownNeighbour;
		}
	}

	uniform_int_distribution<int> neighbourDistribution(0, genomeLength-1);
	int choice = neighbourDistribution(generator);

	// Make sure we're not picking identical values over and over again
	for (int i = 0; i < genomeLength && neighbours[choice] == NULL; i++) {
		choice = neighbourDistribution(generator);
	}

	if (neighbours[choice] == NULL) return target->deepCopy();

	int targetFitness = target->checkFitness();
	int neighbourFitness = neighbours[choice]->checkFitness();

	Individual * neighbour = neighbours[choice]->deepCopy();
	for (int i = 0; i < genomeLength; i++) {
		delete(neighbours[i]);
	}

	free(neighbours);

	if (
		(maximize && targetFitness < neighbourFitness) ||
		(!maximize && targetFitness > neighbourFitness)
	) {
		return neighbour;
	} else {
		float temp = schedule->currentTemp(currentGeneration);
		if (temp == 0) {
			delete(neighbour);
			return target->deepCopy();
		}

		int delta = maximize ? neighbourFitness - targetFitness :
			targetFitness - neighbourFitness;

		float probability = exp(((float)delta)/temp);

		uniform_real_distribution<float>
			goingWrongWayDistribution(0, 1);

		if (goingWrongWayDistribution(generator) < probability) {
			return neighbour;
		} else {
			return target->deepCopy();
		}
	}
}

string SimulatedAnnealer::toString() {
	stringstream ss;

	ss << "Population size: " << populationSize << "\n";
	ss << populationStrings();

	if (!readOnce) ss << "Seed: " << seed << "\n";
	readOnce = true;

	return ss.str();
}
<commit_msg>[SANode]: Kept rewriting SANode<commit_after>#include "nodes/SANode/SANode.hpp"
#include "core/Locus.hpp"
#include <string>
#include <sstream>
#include <iostream>
#include <random>
#include <cmath>

using namespace std;

SANode::SANode(
	int populationSize,
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	populationSize,
	objectives,
	populationToString,
	conditions,
	name
) {
	init(schedule, maximize);
}

SANode::SANode(
	int populationSize,
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	int accelerationFactor,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	populationSize,
	objectives,
	populationToString,
	conditions,
	name,
	accelerationFactor
) {
	init(schedule, maximize);
}

SANode::SANode(
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	1,
	objectives,
	populationToString,
	conditions,
	name
) {
	init(schedule, maximize);
}

SANode::SANode(
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string name,
	int accelerationFactor,
	TemperatureSchedule * schedule,
	bool maximize
) : PopulationNode(
	1,
	objectives,
	populationToString,
	conditions,
	name,
	accelerationFactor
) {
	init(schedule, maximize);
}

void SANode::init(bool maximize, TemperatureSchedule * schedule) {
	this->maximize = maximize;
	this->schedule = schedule;
}

vector<Genome*> SANode::getNextPopulation() {
	vector<Genome*> newPopulation;

	for (int i = 0; i < this->populationSize(); i++) {
		newPopulation.push_back(getNeighbour(this->population[i]));
	}

	return newPopulation;
}

int SANode::compareNeighbourliness(Genome * base, Genome * target) {
	return base->difference(target);
}

// TODO: Break this down further at some point
vector<Genome*> SANode::getAllNeighbours(Genome * target) {
	vector<Genome*> neighbours;
	vector<Locus*> loci = target->getLoci();
	vector<int> rawGenes = target->getGenome();
	vector<int> tempGenes = rawGenes;

	for (int i = 0; i < target->genomeLength(); i++) {
		if (loci[i]->isConstructive()) {
			Genome * nearestKnownNeighbour, tempGenome;
			int top = loci[i]->topIndex();
			int lowestDiff = 0, diff = 0;

			for (int k = 0; k <= top; k++) {
				// So we're not checking against ourselves
				if (rawGenes[i] == k) (k < top) ? k++ : break;

				tempGenes = rawGenes;
				tempGenes[i] = k;
				tempGenome = new Genome(tempGenes, loci);

				diff = this->compareNeighbourliness(
					target,
					tempGenome
				);

				if ((diff < lowestDiff && diff > 0)
					|| lowestDiff == 0
				) {
					delete(nearestKnownNeighbour);
					nearestKnownNeighbour = tempGenome;
					lowestDiff = diff;
				} else {
					delete(tempGenome);
				}
			}

			if (lowestDiff > 0) {
				neighbours.push_back(nearestKnownNeighbour);
			}
		} else {
			// For simple locus types, just increment/decrement
			// and be done with it
			if (!loci[i]->outOfRange(rawGenes[i]+1)) {
				tempGenes[i]++;
				neighbours.push_back(
					new Genome(rawGenes, loci)
				);
			}

			tempGenes = rawGenes;
			if (!loci[i]->outOfRange(rawGenes[i]-1)) {
				tempGenes[i]--;
				neighbours.push_back(
					new Genome(rawGenes, loci)
				);
			}
		}
	}

	return neighbours;
}

Genome * SANode::getNeighbour(Genome * target) {
	vector<Genome*> neighbours = this->getAllNeighbours(target);
	uniform_int_distribution<int> neighbourDist(0, neighbours.size() - 1);
	int neighbour = neighbourDistribution(generator);
}

// Oh God, why did I write it like this?
Individual * SimulatedAnnealer::getNeighbour(Individual * target) {
/*	uniform_int_distribution<int> neighbourDistribution(0, genomeLength-1);
	int choice = neighbourDistribution(generator);

	// Make sure we're not picking identical values over and over again
	for (int i = 0; i < genomeLength && neighbours[choice] == NULL; i++) {
		choice = neighbourDistribution(generator);
	}

	if (neighbours[choice] == NULL) return target->deepCopy();*/

	int targetFitness = target->checkFitness();
	int neighbourFitness = neighbours[choice]->checkFitness();

	Individual * neighbour = neighbours[choice]->deepCopy();
	for (int i = 0; i < genomeLength; i++) {
		delete(neighbours[i]);
	}

	free(neighbours);

	if (
		(maximize && targetFitness < neighbourFitness) ||
		(!maximize && targetFitness > neighbourFitness)
	) {
		return neighbour;
	} else {
		float temp = schedule->currentTemp(currentGeneration);
		if (temp == 0) {
			delete(neighbour);
			return target->deepCopy();
		}

		int delta = maximize ? neighbourFitness - targetFitness :
			targetFitness - neighbourFitness;

		float probability = exp(((float)delta)/temp);

		uniform_real_distribution<float>
			goingWrongWayDistribution(0, 1);

		if (goingWrongWayDistribution(generator) < probability) {
			return neighbour;
		} else {
			return target->deepCopy();
		}
	}
}

string SimulatedAnnealer::toString() {
	stringstream ss;

	ss << "Population size: " << populationSize << "\n";
	ss << populationStrings();

	if (!readOnce) ss << "Seed: " << seed << "\n";
	readOnce = true;

	return ss.str();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TypeGeneration.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-11-11 13:32:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COMPHELPER_TYPEGENERATION_HXX_
#define _COMPHELPER_TYPEGENERATION_HXX_

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef INCLUDED_COMPHELPERDLLAPI_H
#include "comphelper/comphelperdllapi.h"
#endif

#define CPPU_E2T(type)      ((com::sun::star::uno::Type*)type)

namespace com { namespace sun { namespace star { namespace uno {
    class Type;
} } } }
namespace comphelper
{
    enum CppuTypes
    {
        CPPUTYPE_UNKNOWN,           // 0 == unknown == error!!!!

        CPPUTYPE_BOOLEAN,           //getBooleanCppuType()
        CPPUTYPE_INT8,              //getCppuType( (sal_Int8*)0 )
        CPPUTYPE_INT16,             //getCppuType( (sal_Int16*)0 )
        CPPUTYPE_INT32,             //getCppuType( (sal_Int32*)0 )
        CPPUTYPE_DOUBLE,            //getCppuType( (double*)0 )
        CPPUTYPE_FLOAT,             //getCppuType( (float*)0 )
        CPPUTYPE_OUSTRING,          //getCppuType( (OUString*)0 )

        CPPUTYPE_FONTSLANT,         //getCppuType( (FontSlant*)0 )
        CPPUTYPE_LOCALE,            //getCppuType( (Locale*)0 )
        CPPUTYPE_PROPERTYVALUE,     //getCppuType( (Sequence<PropertyValue>*)0 )
        CPPUTYPE_PROPERTYVALUES,    //getCppuType( (Sequence<PropertyValues>*)0 )
        CPPUTYPE_BORDERLINE,        //getCppuType( (table::BorderLine*)0 )
        CPPUTYPE_BREAK,             //getCppuType( (style::BreakType*)0 )
        CPPUTYPE_GRAPHICLOC,        //getCppuType( (style::GraphicLocation*)0 )
        CPPUTYPE_DROPCAPFMT,        //getCppuType( (style::DropCapFormat*)0 )
        CPPUTYPE_LINESPACE,         //getCppuType( (style::LineSpacing*)0 )
        CPPUTYPE_AWTSIZE,           //getCppuType( (awt::Size*)0 )
        CPPUTYPE_SHADOWFMT,         //getCppuType( (table::ShadowFormat*)0 )
        CPPUTYPE_TBLCOLSEP,         //getCppuType( (Sequence<text::TableColumnSeparator>*)0 )
        CPPUTYPE_PNTSEQSEQ,         //getCppuType( (PointSequenceSequence*)0 )
        CPPUTYPE_DOCIDXMRK,         //getCppuType( (Sequence< Reference< XDocumentIndexMark > >*)0 )
        CPPUTYPE_SEQINT8,           //getCppuType( (Sequence<sal_Int8>*)0 )
        CPPUTYPE_SEQTABSTOP,        //getCppuType( (Sequence<style::TabStop>*)0 )
        CPPUTYPE_SEQANCHORTYPE,     //getCppuType( (Sequence<text::TextContentAnchorType>*)0 )
        CPPUTYPE_SEQDEPTXTFLD,      //getCppuType( (Sequence<Reference<XDependentTextField> >*)0 )
        CPPUTYPE_TXTCNTANCHOR,      //getCppuType( (text::TextContentAnchorType*)0 )
        CPPUTYPE_WRAPTXTMODE,       //getCppuType( (text::WrapTextMode*)0 )
        CPPUTYPE_COLORMODE,         //getCppuType( (drawing::ColorMode*)0 )
        CPPUTYPE_PAGESTYLELAY,      //getCppuType( (style::PageStyleLayout*)0 )
        CPPUTYPE_VERTALIGN,         //getCppuType( (style::VerticalAlignment*)0 )
        CPPUTYPE_TABLEBORDER,       //getCppuType( (table::TableBorder*)0 )
        CPPUTYPE_GRFCROP,           //getCppuType( (text::GraphicCrop*)0 )
        CPPUTYPE_SECTFILELNK,       //getCppuType( (text::SectionFileLink*)0 )
        CPPUTYPE_PAGENUMTYPE,       //getCppuType( (const PageNumberType*)0 )
        CPPUTYPE_DATETIME,          //getCppuType( (util::DateTime*)0 )
        CPPUTYPE_DATE,              //getCppuType( (util::Date*)0 )

        CPPUTYPE_REFINTERFACE,      //getCppuType( (Reference<XInterface>*)0 )
        CPPUTYPE_REFIDXREPL,        //getCppuType( (Reference<container::XIndexReplace>*)0 )
        CPPUTYPE_REFNAMECNT,        //getCppuType( (Reference<container::XNameContainer>*)0 )
        CPPUTYPE_REFTEXTFRAME,      //getCppuType( (Reference<text::XTextFrame>*)0 )
        CPPUTYPE_REFTEXTSECTION,    //getCppuType( (Reference<text::XTextSection>*)0 )
        CPPUTYPE_REFFOOTNOTE,       //getCppuType( (Reference<text::XFootnote>*)0 )
        CPPUTYPE_REFTEXT,           //getCppuType( (Reference<text::XText>*)0 )
        CPPUTYPE_REFTEXTCOL,        //getCppuType( (Reference<text::XTextColumns>*)0 )

        CPPUTYPE_REFFORBCHARS,      //getCppuType( (Reference<XForbiddenCharacters>*)0)
        CPPUTYPE_REFIDXCNTNR,       //getCppuType( (Reference<XIndexContainer>*)0)
        CPPUTYPE_REFTEXTCNTNT,      //getCppuType( (Reference<XTextContent>*)0)
        CPPUTYPE_REFBITMAP,         //getCppuType( (Reference<awt::XBitmap>*)0)
        CPPUTYPE_REFNMREPLACE,      //getCppuType( (Reference<container::XNameReplace>*)0)
        CPPUTYPE_REFCELL,           //getCppuType( (Reference<table::XCell>*)0)
        CPPUTYPE_REFDOCINDEX,       //getCppuType( (Reference<text::XDocumentIndex>*)0)
        CPPUTYPE_REFDOCIDXMRK,      //getCppuType( (Reference<text::XDocumentIndexMark>*)0)
        CPPUTYPE_REFTXTFIELD,       //getCppuType( (Reference<text::XTextField>*)0)
        CPPUTYPE_REFTXTRANGE,       //getCppuType( (Reference<text::XTextRange>*)0)
        CPPUTYPE_REFTXTTABLE,       //getCppuType( (Reference<text::XTextTable>*)0)
        CPPUTYPE_AWTPOINT,          //getCppuType( (awt::Point*)0 )
        CPPUTYPE_REFLIBCONTAINER,   //getCppuType( (Reference< script::XLibraryContainer >*)0)
        CPPUTYPE_SEQANY,            //getCppuType( (Sequence< uno::Any >*)0)
        CPPUTYPE_REFRESULTSET,      //getCppuType( (Reference< sdbc::XResultSet >*)0)
        CPPUTYPE_REFCONNECTION,     //getCppuType( (Reference< sdbc::XConnection >*)0)
        CPPUTYPE_REFMODEL,          //getCppuType( (Reference< frame::XModel >*)0)

        CPPUTYPE_OUSTRINGS,         //getCppuType( (Sequence<OUString>*)0 )
        CPPUTYPE_REFCOMPONENT,      //getCppuType( (Reference< lang::XComponent >*)0 )
        // --> OD 2004-08-09 #i28749#
        CPPUTYPE_TRANSFORMATIONINHORIL2R, //getCppuType( (drawing::HomogenMatrix3)* )
        // <--
        CPPUTYPE_SEQNAMEDVALUE,     //getCppuType( (Sequence<beans::NamedValue>*)0 )

        CPPUTYPE_END
    };
    COMPHELPER_DLLPUBLIC void GenerateCppuType ( sal_uInt16 eType, const com::sun::star::uno::Type*& pType );
}
#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.10.8); FILE MERGED 2006/01/25 20:10:52 sb 1.10.8.2: RESYNC: (1.10-1.11); FILE MERGED 2005/12/07 09:04:06 sb 1.10.8.1: #i53898# Made code warning-free.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TypeGeneration.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 22:41:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COMPHELPER_TYPEGENERATION_HXX_
#define _COMPHELPER_TYPEGENERATION_HXX_

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef INCLUDED_COMPHELPERDLLAPI_H
#include "comphelper/comphelperdllapi.h"
#endif

#define CPPU_E2T(type)      ((com::sun::star::uno::Type*)type)

namespace com { namespace sun { namespace star { namespace uno {
    class Type;
} } } }
namespace comphelper
{
    enum CppuTypes
    {
        CPPUTYPE_UNKNOWN,           // 0 == unknown == error!!!!

        CPPUTYPE_BOOLEAN,           //getBooleanCppuType()
        CPPUTYPE_INT8,              //getCppuType( (sal_Int8*)0 )
        CPPUTYPE_INT16,             //getCppuType( (sal_Int16*)0 )
        CPPUTYPE_INT32,             //getCppuType( (sal_Int32*)0 )
        CPPUTYPE_DOUBLE,            //getCppuType( (double*)0 )
        CPPUTYPE_FLOAT,             //getCppuType( (float*)0 )
        CPPUTYPE_OUSTRING,          //getCppuType( (OUString*)0 )

        CPPUTYPE_FONTSLANT,         //getCppuType( (FontSlant*)0 )
        CPPUTYPE_LOCALE,            //getCppuType( (Locale*)0 )
        CPPUTYPE_PROPERTYVALUE,     //getCppuType( (Sequence<PropertyValue>*)0 )
        CPPUTYPE_PROPERTYVALUES,    //getCppuType( (Sequence<PropertyValues>*)0 )
        CPPUTYPE_BORDERLINE,        //getCppuType( (table::BorderLine*)0 )
        CPPUTYPE_BREAK,             //getCppuType( (style::BreakType*)0 )
        CPPUTYPE_GRAPHICLOC,        //getCppuType( (style::GraphicLocation*)0 )
        CPPUTYPE_DROPCAPFMT,        //getCppuType( (style::DropCapFormat*)0 )
        CPPUTYPE_LINESPACE,         //getCppuType( (style::LineSpacing*)0 )
        CPPUTYPE_AWTSIZE,           //getCppuType( (awt::Size*)0 )
        CPPUTYPE_SHADOWFMT,         //getCppuType( (table::ShadowFormat*)0 )
        CPPUTYPE_TBLCOLSEP,         //getCppuType( (Sequence<text::TableColumnSeparator>*)0 )
        CPPUTYPE_PNTSEQSEQ,         //getCppuType( (PointSequenceSequence*)0 )
        CPPUTYPE_DOCIDXMRK,         //getCppuType( (Sequence< Reference< XDocumentIndexMark > >*)0 )
        CPPUTYPE_SEQINT8,           //getCppuType( (Sequence<sal_Int8>*)0 )
        CPPUTYPE_SEQTABSTOP,        //getCppuType( (Sequence<style::TabStop>*)0 )
        CPPUTYPE_SEQANCHORTYPE,     //getCppuType( (Sequence<text::TextContentAnchorType>*)0 )
        CPPUTYPE_SEQDEPTXTFLD,      //getCppuType( (Sequence<Reference<XDependentTextField> >*)0 )
        CPPUTYPE_TXTCNTANCHOR,      //getCppuType( (text::TextContentAnchorType*)0 )
        CPPUTYPE_WRAPTXTMODE,       //getCppuType( (text::WrapTextMode*)0 )
        CPPUTYPE_COLORMODE,         //getCppuType( (drawing::ColorMode*)0 )
        CPPUTYPE_PAGESTYLELAY,      //getCppuType( (style::PageStyleLayout*)0 )
        CPPUTYPE_VERTALIGN,         //getCppuType( (style::VerticalAlignment*)0 )
        CPPUTYPE_TABLEBORDER,       //getCppuType( (table::TableBorder*)0 )
        CPPUTYPE_GRFCROP,           //getCppuType( (text::GraphicCrop*)0 )
        CPPUTYPE_SECTFILELNK,       //getCppuType( (text::SectionFileLink*)0 )
        CPPUTYPE_PAGENUMTYPE,       //getCppuType( (const PageNumberType*)0 )
        CPPUTYPE_DATETIME,          //getCppuType( (util::DateTime*)0 )
        CPPUTYPE_DATE,              //getCppuType( (util::Date*)0 )

        CPPUTYPE_REFINTERFACE,      //getCppuType( (Reference<XInterface>*)0 )
        CPPUTYPE_REFIDXREPL,        //getCppuType( (Reference<container::XIndexReplace>*)0 )
        CPPUTYPE_REFNAMECNT,        //getCppuType( (Reference<container::XNameContainer>*)0 )
        CPPUTYPE_REFTEXTFRAME,      //getCppuType( (Reference<text::XTextFrame>*)0 )
        CPPUTYPE_REFTEXTSECTION,    //getCppuType( (Reference<text::XTextSection>*)0 )
        CPPUTYPE_REFFOOTNOTE,       //getCppuType( (Reference<text::XFootnote>*)0 )
        CPPUTYPE_REFTEXT,           //getCppuType( (Reference<text::XText>*)0 )
        CPPUTYPE_REFTEXTCOL,        //getCppuType( (Reference<text::XTextColumns>*)0 )

        CPPUTYPE_REFFORBCHARS,      //getCppuType( (Reference<XForbiddenCharacters>*)0)
        CPPUTYPE_REFIDXCNTNR,       //getCppuType( (Reference<XIndexContainer>*)0)
        CPPUTYPE_REFTEXTCNTNT,      //getCppuType( (Reference<XTextContent>*)0)
        CPPUTYPE_REFBITMAP,         //getCppuType( (Reference<awt::XBitmap>*)0)
        CPPUTYPE_REFNMREPLACE,      //getCppuType( (Reference<container::XNameReplace>*)0)
        CPPUTYPE_REFCELL,           //getCppuType( (Reference<table::XCell>*)0)
        CPPUTYPE_REFDOCINDEX,       //getCppuType( (Reference<text::XDocumentIndex>*)0)
        CPPUTYPE_REFDOCIDXMRK,      //getCppuType( (Reference<text::XDocumentIndexMark>*)0)
        CPPUTYPE_REFTXTFIELD,       //getCppuType( (Reference<text::XTextField>*)0)
        CPPUTYPE_REFTXTRANGE,       //getCppuType( (Reference<text::XTextRange>*)0)
        CPPUTYPE_REFTXTTABLE,       //getCppuType( (Reference<text::XTextTable>*)0)
        CPPUTYPE_AWTPOINT,          //getCppuType( (awt::Point*)0 )
        CPPUTYPE_REFLIBCONTAINER,   //getCppuType( (Reference< script::XLibraryContainer >*)0)
        CPPUTYPE_SEQANY,            //getCppuType( (Sequence< uno::Any >*)0)
        CPPUTYPE_REFRESULTSET,      //getCppuType( (Reference< sdbc::XResultSet >*)0)
        CPPUTYPE_REFCONNECTION,     //getCppuType( (Reference< sdbc::XConnection >*)0)
        CPPUTYPE_REFMODEL,          //getCppuType( (Reference< frame::XModel >*)0)

        CPPUTYPE_OUSTRINGS,         //getCppuType( (Sequence<OUString>*)0 )
        CPPUTYPE_REFCOMPONENT,      //getCppuType( (Reference< lang::XComponent >*)0 )
        // --> OD 2004-08-09 #i28749#
        CPPUTYPE_TRANSFORMATIONINHORIL2R, //getCppuType( (drawing::HomogenMatrix3)* )
        // <--
        CPPUTYPE_SEQNAMEDVALUE,     //getCppuType( (Sequence<beans::NamedValue>*)0 )

        CPPUTYPE_END
    };
    COMPHELPER_DLLPUBLIC void GenerateCppuType (
        CppuTypes eType, const com::sun::star::uno::Type*& pType );
}
#endif
<|endoftext|>


<commit_before>#include "SocketUtilities.h"
#include <limits>
#include <unistd.h>
#include <atomic>
#include <vector>
#include <sstream>
#include <string>
#include <sys/socket.h>

// MSG_NOSIGNAL doesn't exist on Mac OSX
#if defined(__APPLE__)
    #define MSG_NOSIGNAL SO_NOSIGPIPE
#endif

class SocketUtilities::SocketException : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

/*
 * Redefine standard aliases and alias the STL types used
 */
using SocketType = SocketUtilities::SocketType;
using SocketException = SocketUtilities::SocketException;
using BufferType = SocketUtilities::BufferType;
using std::ostringstream;
using std::cout;
using std::endl;
using std::ostream;
using std::string;
using std::to_string;

/*
 * The standard stream to which logged messages are displayed.
 */
static ostream* log_stream = &std::cout;

/*
 * Defaulted compile time logging utility for this class.  Optimized away at
 * compile time when the network log is not required
 */
static std::atomic<bool> __log_mutex (false);
template <bool output> void _log_output(string output_message);
template <> void _log_output<true> (string output_message) {

    // spin and acquire the lock
    while (__log_mutex.exchange(false)) {}
        *log_stream << "@@@ Network Log @@@  " << output_message <<
            (output_message.back() == '\n' ? "" : "\n");
    __log_mutex.store(false);
}
template <> void _log_output<false> (string output_message) {}
static constexpr void (*log_output) (string output_message) =
    _log_output<log_events>;

/******************************************************************************
 ************************* FUNCTION IMPLEMENTIONS *****************************
 ******************************************************************************/
void SocketUtilities::set_log_stream(std::ostream& log_stream_in) {
    log_stream = &log_stream_in;
}

SocketType SocketUtilities::create_server_socket(const char* port, int backlog) {

    SocketType socket_to_return;

    // ****************************** STEP 1 **********************************
    // ************************************************************************
    // Create the addrinfo struct to get the information needed to bind
    addrinfo hints, *server_address_information;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;        // ipv4 or ipv6
    hints.ai_socktype = SOCK_STREAM;    // TCP socket
    hints.ai_flags = AI_PASSIVE;        // Automatically fill in my IP

    // getaddrinfo to get the results of the internet address on which to bind
    // the socket connection
    int return_value;
    if ((return_value =
          getaddrinfo(nullptr, port, &hints, &server_address_information)) != 0) {
        throw SocketException( (ostringstream() << "getaddrinfo: " <<
                    gai_strerror(return_value)).str() );
    }

    // loop through the results from getaddrinfo
    { addrinfo* i;
    for (i = server_address_information; i; i = i->ai_next) {

        // continue if this fails
        if ((socket_to_return = socket(i->ai_family, i->ai_socktype,
                i->ai_protocol)) == -1) {
            perror("server: socket");
            continue;
        }

        // exit if setsockopt fails
        int yes = 1;
        if (setsockopt(socket_to_return, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(int)) == -1) {
            perror("setsockopt");
            throw SocketException("Error in setsockopt");
        }

        // continue trying if this fails
        if (::bind(socket_to_return, i->ai_addr, i->ai_addrlen) == -1) {
            close(socket_to_return);
            perror("server: bind");
            continue;
        }

        break;
    }
    freeaddrinfo(server_address_information);
    if (!i) {
        throw SocketException("Failed to bind to this machine's IP and "
                "port specified");
    } }
    // ************************************************************************
    // ****************************** STEP 1 **********************************

    // ****************************** STEP 2 **********************************
    // ************************************************************************
    if (listen(socket_to_return, backlog) == -1) {
        perror("listen");
        throw SocketException("error in listen()");
    }

    // log output
    log_output(string("Created server socket ") + to_string(socket_to_return));

    return socket_to_return;
}

auto SocketUtilities::recv(SocketType sock_fd, void* buffer,
        size_t length, int flags) -> decltype (::recv(0,0,0,0)) {

    // Print to the network log
    log_output(string("Called recv() on socket ") + to_string(sock_fd));

    // Make the system call and handle errors
    auto n = ::recv(sock_fd, buffer, length, flags);
    if (n == -1) {
        throw SocketUtilities::SocketException(
                string("Error calling recv() : ") + string (strerror(errno)));
    } else if (!n) {
        throw SocketUtilities::SocketException(
                string("Error calling recv() : ") + string (strerror(errno)));
    }

    // print to network log again
    log_output(string("Received data from socket ") + to_string(sock_fd) +
            string("\n") + string((char*)buffer, ((char*)buffer) + n));

    return n;
}

BufferType SocketUtilities::receive (SocketType sock_fd,
        size_t length, unsigned flags) {

    auto bytes_received = decltype(length)(0);
    BufferType buffer (length);

    // loop and receive data
    while (bytes_received < length) {
        int received = SocketUtilities::recv(sock_fd,
                (void*) (buffer.data() + bytes_received),
                length - bytes_received,
                flags);
        bytes_received += received;
    }

    return buffer;
}

void SocketUtilities::send(SocketType sock_fd, BufferType data_to_send) {

    // loop and send data
    int bytes_sent = 0;
    while (bytes_sent < data_to_send.size()) {
        int sent = ::send(sock_fd, data_to_send.data() + bytes_sent,
                data_to_send.size() - bytes_sent, MSG_NOSIGNAL);

        // handle exceptional condition
        if (sent == -1) {
            throw SocketException(string("Error sending data to socket ") +
                    to_string(sock_fd));
        }

        // print to log if logging is turned on
        log_output(string("Called send() on socket ") + to_string(sock_fd) +
                string(" : sent ") + to_string(sent) + string(" bytes\n") +
                string(data_to_send.data() + bytes_sent,
                    data_to_send.data() + bytes_sent + sent));

        bytes_sent += sent;
    }

}

SocketType SocketUtilities::accept(SocketType sock_fd,
        sockaddr* address, socklen_t* address_length) {

    auto to_return_socket = ::accept(sock_fd, address, address_length);
    if (to_return_socket == -1) {
        perror("accept");
        throw SocketException("Error calling accept()");
    }

    log_output(string("Accepted new connection on socket ") +
            to_string(to_return_socket));
    return to_return_socket;
}
/******************************************************************************
 ************************* FUNCTION IMPLEMENTIONS *****************************
 ******************************************************************************/

/******************************************************************************
 *********************** The RAII wrapper for sockets *************************
 ******************************************************************************/
using SocketRAII = SocketUtilities::SocketRAII;
const SocketType SocketRAII::null_socket = std::numeric_limits<SocketType>::max();

void SocketRAII::release() {
    if (this->owned_socket != SocketRAII::null_socket) {
        close(this->owned_socket);
        this->owned_socket = SocketRAII::null_socket;
    }
}

SocketRAII::SocketRAII(int sock_fd) : owned_socket(sock_fd) {}
SocketRAII::~SocketRAII() {
    this->release();
}
SocketRAII::SocketRAII(SocketRAII&& other) {
    this->owned_socket = other.owned_socket;
    other.owned_socket = SocketRAII::null_socket;
}

SocketRAII::operator SocketType () { return this->owned_socket; }
/******************************************************************************
 *********************** The RAII wrapper for sockets *************************
 ******************************************************************************/

/*
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
*/
<commit_msg>Made log messages more uniform<commit_after>#include "SocketUtilities.h"
#include <limits>
#include <unistd.h>
#include <atomic>
#include <vector>
#include <sstream>
#include <string>
#include <sys/socket.h>

// MSG_NOSIGNAL doesn't exist on Mac OSX
#if defined(__APPLE__)
    #define MSG_NOSIGNAL SO_NOSIGPIPE
#endif

class SocketUtilities::SocketException : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

/*
 * Redefine standard aliases and alias the STL types used
 */
using SocketType = SocketUtilities::SocketType;
using SocketException = SocketUtilities::SocketException;
using BufferType = SocketUtilities::BufferType;
using std::ostringstream;
using std::cout;
using std::endl;
using std::ostream;
using std::string;
using std::to_string;

/*
 * The standard stream to which logged messages are displayed.
 */
static ostream* log_stream = &std::cout;

/*
 * Defaulted compile time logging utility for this class.  Optimized away at
 * compile time when the network log is not required
 */
static std::atomic<bool> __log_mutex (false);
template <bool output> void _log_output(string output_message);
template <> void _log_output<true> (string output_message) {

    // spin and acquire the lock
    while (__log_mutex.exchange(false)) {}
        *log_stream << "@@@ Network Log @@@  " << output_message <<
            (output_message.back() == '\n' ? "" : "\n");
    __log_mutex.store(false);
}
template <> void _log_output<false> (string output_message) {}
static constexpr void (*log_output) (string output_message) =
    _log_output<log_events>;

/******************************************************************************
 ************************* FUNCTION IMPLEMENTIONS *****************************
 ******************************************************************************/
void SocketUtilities::set_log_stream(std::ostream& log_stream_in) {
    log_stream = &log_stream_in;
}

SocketType SocketUtilities::create_server_socket(const char* port, int backlog) {

    SocketType socket_to_return;

    // ****************************** STEP 1 **********************************
    // ************************************************************************
    // Create the addrinfo struct to get the information needed to bind
    addrinfo hints, *server_address_information;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;        // ipv4 or ipv6
    hints.ai_socktype = SOCK_STREAM;    // TCP socket
    hints.ai_flags = AI_PASSIVE;        // Automatically fill in my IP

    // getaddrinfo to get the results of the internet address on which to bind
    // the socket connection
    int return_value;
    if ((return_value =
          getaddrinfo(nullptr, port, &hints, &server_address_information)) != 0) {
        throw SocketException( (ostringstream() << "getaddrinfo: " <<
                    gai_strerror(return_value)).str() );
    }

    // loop through the results from getaddrinfo
    { addrinfo* i;
    for (i = server_address_information; i; i = i->ai_next) {

        // continue if this fails
        if ((socket_to_return = socket(i->ai_family, i->ai_socktype,
                i->ai_protocol)) == -1) {
            perror("server: socket");
            continue;
        }

        // exit if setsockopt fails
        int yes = 1;
        if (setsockopt(socket_to_return, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(int)) == -1) {
            perror("setsockopt");
            throw SocketException("Error in setsockopt");
        }

        // continue trying if this fails
        if (::bind(socket_to_return, i->ai_addr, i->ai_addrlen) == -1) {
            close(socket_to_return);
            perror("server: bind");
            continue;
        }

        break;
    }
    freeaddrinfo(server_address_information);
    if (!i) {
        throw SocketException("Failed to bind to this machine's IP and "
                "port specified");
    } }
    // ************************************************************************
    // ****************************** STEP 1 **********************************

    // ****************************** STEP 2 **********************************
    // ************************************************************************
    if (listen(socket_to_return, backlog) == -1) {
        perror("listen");
        throw SocketException("error in listen()");
    }

    // log output
    log_output(string("Created server socket ") + to_string(socket_to_return));

    return socket_to_return;
}

auto SocketUtilities::recv(SocketType sock_fd, void* buffer,
        size_t length, int flags) -> decltype (::recv(0,0,0,0)) {

    // Make the system call and handle errors
    auto n = ::recv(sock_fd, buffer, length, flags);
    if (n == -1) {
        throw SocketUtilities::SocketException(
                string("Error calling recv() : ") + string (strerror(errno)));
    } else if (!n) {
        throw SocketUtilities::SocketException(
                string("Error calling recv() : ") + string (strerror(errno)));
    }

    // Print to the network log
    log_output(string("Called recv() on socket ") + to_string(sock_fd) +
            string(" : ") + string("received ") + to_string(n) +
            string(" bytes\n") + string((char*)buffer, ((char*)buffer) + n));

    return n;
}

BufferType SocketUtilities::receive (SocketType sock_fd,
        size_t length, unsigned flags) {

    auto bytes_received = decltype(length)(0);
    BufferType buffer (length);

    // loop and receive data
    while (bytes_received < length) {
        int received = SocketUtilities::recv(sock_fd,
                (void*) (buffer.data() + bytes_received),
                length - bytes_received,
                flags);
        bytes_received += received;
    }

    return buffer;
}

void SocketUtilities::send(SocketType sock_fd, BufferType data_to_send) {

    // loop and send data
    int bytes_sent = 0;
    while (bytes_sent < data_to_send.size()) {
        int sent = ::send(sock_fd, data_to_send.data() + bytes_sent,
                data_to_send.size() - bytes_sent, MSG_NOSIGNAL);

        // handle exceptional condition
        if (sent == -1) {
            throw SocketException(string("Error sending data to socket ") +
                    to_string(sock_fd));
        }

        // print to log if logging is turned on
        log_output(string("Called send() on socket ") + to_string(sock_fd) +
                string(" : sent ") + to_string(sent) + string(" bytes\n") +
                string(data_to_send.data() + bytes_sent,
                    data_to_send.data() + bytes_sent + sent));

        bytes_sent += sent;
    }

}

SocketType SocketUtilities::accept(SocketType sock_fd,
        sockaddr* address, socklen_t* address_length) {

    auto to_return_socket = ::accept(sock_fd, address, address_length);
    if (to_return_socket == -1) {
        perror("accept");
        throw SocketException("Error calling accept()");
    }

    log_output(string("Accepted new connection on socket ") +
            to_string(to_return_socket));
    return to_return_socket;
}
/******************************************************************************
 ************************* FUNCTION IMPLEMENTIONS *****************************
 ******************************************************************************/

/******************************************************************************
 *********************** The RAII wrapper for sockets *************************
 ******************************************************************************/
using SocketRAII = SocketUtilities::SocketRAII;
const SocketType SocketRAII::null_socket = std::numeric_limits<SocketType>::max();

void SocketRAII::release() {
    if (this->owned_socket != SocketRAII::null_socket) {
        close(this->owned_socket);
        this->owned_socket = SocketRAII::null_socket;
    }
}

SocketRAII::SocketRAII(int sock_fd) : owned_socket(sock_fd) {}
SocketRAII::~SocketRAII() {
    this->release();
}
SocketRAII::SocketRAII(SocketRAII&& other) {
    this->owned_socket = other.owned_socket;
    other.owned_socket = SocketRAII::null_socket;
}

SocketRAII::operator SocketType () { return this->owned_socket; }
/******************************************************************************
 *********************** The RAII wrapper for sockets *************************
 ******************************************************************************/

/*
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
*/
<|endoftext|>


<commit_before>/*
 * A miniapp that demonstrates how to make a ring model
 *
 */

#include <fstream>
#include <iomanip>
#include <iostream>

#include <nlohmann/json.hpp>

#include <arbor/assert_macro.hpp>
#include <arbor/common_types.hpp>
#include <arbor/context.hpp>
#include <arbor/load_balance.hpp>
#include <arbor/mc_cell.hpp>
#include <arbor/profile/meter_manager.hpp>
#include <arbor/profile/profiler.hpp>
#include <arbor/simple_sampler.hpp>
#include <arbor/simulation.hpp>
#include <arbor/recipe.hpp>
#include <arbor/version.hpp>

#include <aux/ioutil.hpp>
#include <aux/json_meter.hpp>

#include "parameters.hpp"

#ifdef ARB_MPI_ENABLED
#include <mpi.h>
#include <aux/with_mpi.hpp>
#endif

using arb::cell_gid_type;
using arb::cell_lid_type;
using arb::cell_size_type;
using arb::cell_member_type;
using arb::cell_kind;
using arb::time_type;
using arb::cell_probe_address;

// Writes voltage trace as a json file.
void write_trace_json(const arb::trace_data<double>& trace);

// Generate a cell.
arb::mc_cell branch_cell(arb::cell_gid_type gid, const cell_parameters& params);

class ring_recipe: public arb::recipe {
public:
    ring_recipe(unsigned num_cells, cell_parameters params, unsigned min_delay):
        num_cells_(num_cells),
        cell_params_(params),
        min_delay_(min_delay)
    {}

    cell_size_type num_cells() const override {
        return num_cells_;
    }

    arb::util::unique_any get_cell_description(cell_gid_type gid) const override {
        return branch_cell(gid, cell_params_);
    }

    cell_kind get_cell_kind(cell_gid_type gid) const override {
        return cell_kind::cable1d_neuron;
    }

    // Each cell has one spike detector (at the soma).
    cell_size_type num_sources(cell_gid_type gid) const override {
        return 1;
    }

    // The cell has one target synapse, which will be connected to cell gid-1.
    cell_size_type num_targets(cell_gid_type gid) const override {
        return 1;
    }

    // Each cell has one incoming connection, from cell with gid-1.
    std::vector<arb::cell_connection> connections_on(cell_gid_type gid) const override {
        cell_gid_type src = gid? gid-1: num_cells_-1;
        return {arb::cell_connection({src, 0}, {gid, 0}, event_weight_, min_delay_)};
    }

    // Return one event generator on gid 0. This generates a single event that will
    // kick start the spiking.
    std::vector<arb::event_generator> event_generators(cell_gid_type gid) const override {
        std::vector<arb::event_generator> gens;
        if (!gid) {
            gens.push_back(arb::explicit_generator(arb::pse_vector{{{0, 0}, event_weight_, 1.0}}));
        }
        return gens;
    }

    // There is one probe (for measuring voltage at the soma) on the cell.
    cell_size_type num_probes(cell_gid_type gid)  const override {
        return 1;
    }

    arb::probe_info get_probe(cell_member_type id) const override {
        // Get the appropriate kind for measuring voltage.
        cell_probe_address::probe_kind kind = cell_probe_address::membrane_voltage;
        // Measure at the soma.
        arb::segment_location loc(0, 0.0);

        return arb::probe_info{id, kind, cell_probe_address{loc, kind}};
    }

private:
    cell_size_type num_cells_;
    cell_parameters cell_params_;
    double min_delay_;
    float event_weight_ = 0.05;
};

struct cell_stats {
    using size_type = unsigned;
    size_type ncells = 0;
    size_type nsegs = 0;
    size_type ncomp = 0;

    cell_stats(arb::recipe& r) {
#ifdef ARB_MPI_ENABLED
        int nranks, rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &nranks);
        ncells = r.num_cells();
        size_type cells_per_rank = ncells/nranks;
        size_type b = rank*cells_per_rank;
        size_type e = (rank==nranks-1)? ncells: (rank+1)*cells_per_rank;
        size_type nsegs_tmp = 0;
        size_type ncomp_tmp = 0;
        for (size_type i=b; i<e; ++i) {
            auto c = arb::util::any_cast<arb::mc_cell>(r.get_cell_description(i));
            nsegs_tmp += c.num_segments();
            ncomp_tmp += c.num_compartments();
        }
        MPI_Allreduce(&nsegs_tmp, &nsegs, 1, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD);
        MPI_Allreduce(&ncomp_tmp, &ncomp, 1, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD);
#else
        ncells = r.num_cells();
        for (size_type i=0; i<ncells; ++i) {
            auto c = arb::util::any_cast<arb::mc_cell>(r.get_cell_description(i));
            nsegs += c.num_segments();
            ncomp += c.num_compartments();
        }
#endif
    }

    friend std::ostream& operator<<(std::ostream& o, const cell_stats& s) {
        return o << "cell stats: "
                 << s.ncells << " cells; "
                 << s.nsegs << " segments; "
                 << s.ncomp << " compartments.";
    }
};

int main(int argc, char** argv) {
    try {
        bool root = true;

#ifdef ARB_MPI_ENABLED
        aux::with_mpi guard(argc, argv, false);
        auto context = arb::make_context(arb::proc_allocation(), MPI_COMM_WORLD);
        {
            int rank;
            MPI_Comm_rank(MPI_COMM_WORLD, &rank);
            root = rank==0;
        }
#else
        auto context = arb::make_context();
#endif

#ifdef ARB_PROFILE_ENABLED
        arb::profile::profiler_initialize(context);
#endif

        std::cout << aux::mask_stream(root);

        // Print a banner with information about hardware configuration
        std::cout << "gpu:      " << (has_gpu(context)? "yes": "no") << "\n";
        std::cout << "threads:  " << num_threads(context) << "\n";
        std::cout << "mpi:      " << (has_mpi(context)? "yes": "no") << "\n";
        std::cout << "ranks:    " << num_ranks(context) << "\n" << std::endl;

        auto params = read_options(argc, argv);

        arb::profile::meter_manager meters;
        meters.start(context);

        // Create an instance of our recipe.
        ring_recipe recipe(params.num_cells, params.cell, params.min_delay);
        cell_stats stats(recipe);
        std::cout << stats << "\n";

        auto decomp = arb::partition_load_balance(recipe, context);

        // Construct the model.
        arb::simulation sim(recipe, decomp, context);

        // Set up the probe that will measure voltage in the cell.

        // The id of the only probe on the cell: the cell_member type points to (cell 0, probe 0)
        auto probe_id = cell_member_type{0, 0};
        // The schedule for sampling is 10 samples every 1 ms.
        auto sched = arb::regular_schedule(0.1);
        // This is where the voltage samples will be stored as (time, value) pairs
        arb::trace_data<double> voltage;
        // Now attach the sampler at probe_id, with sampling schedule sched, writing to voltage
        sim.add_sampler(arb::one_probe(probe_id), sched, arb::make_simple_sampler(voltage));

        // Set up recording of spikes to a vector on the root process.
        std::vector<arb::spike> recorded_spikes;
        if (root) {
            sim.set_global_spike_callback(
                [&recorded_spikes](const std::vector<arb::spike>& spikes) {
                    recorded_spikes.insert(recorded_spikes.end(), spikes.begin(), spikes.end());
                });
        }

        meters.checkpoint("model-init", context);

        std::cout << "running simulation" << std::endl;
        // Run the simulation for 100 ms, with time steps of 0.025 ms.
        sim.run(params.duration, 0.025);

        meters.checkpoint("model-run", context);

        auto ns = sim.num_spikes();

        // Write spikes to file
        if (root) {
            std::cout << "\n" << ns << " spikes generated at rate of "
                      << params.duration/ns << " ms between spikes\n";
            std::ofstream fid("spikes.gdf");
            if (!fid.good()) {
                std::cerr << "Warning: unable to open file spikes.gdf for spike output\n";
            }
            else {
                char linebuf[45];
                for (auto spike: recorded_spikes) {
                    auto n = std::snprintf(
                        linebuf, sizeof(linebuf), "%u %.4f\n",
                        unsigned{spike.source.gid}, float(spike.time));
                    fid.write(linebuf, n);
                }
            }
        }

        // Write the samples to a json file.
        if (root) write_trace_json(voltage);

        auto report = arb::profile::make_meter_report(meters, context);
        std::cout << report;
    }
    catch (std::exception& e) {
        std::cerr << "exception caught in ring miniapp:\n" << e.what() << "\n";
        return 1;
    }

    return 0;
}

void write_trace_json(const arb::trace_data<double>& trace) {
    std::string path = "./voltages.json";

    nlohmann::json json;
    json["name"] = "ring demo";
    json["units"] = "mV";
    json["cell"] = "0.0";
    json["probe"] = "0";

    auto& jt = json["data"]["time"];
    auto& jy = json["data"]["voltage"];

    for (const auto& sample: trace) {
        jt.push_back(sample.t);
        jy.push_back(sample.v);
    }

    std::ofstream file(path);
    file << std::setw(1) << json << "\n";
}

// Helper used to interpolate in branch_cell.
template <typename T>
double interp(const std::array<T,2>& r, unsigned i, unsigned n) {
    double p = i * 1./(n-1);
    double r0 = r[0];
    double r1 = r[1];
    return r[0] + p*(r1-r0);
}

arb::mc_cell branch_cell(arb::cell_gid_type gid, const cell_parameters& params) {
    arb::mc_cell cell;

    // Add soma.
    auto soma = cell.add_soma(12.6157/2.0); // For area of 500 μm².
    soma->rL = 100;
    soma->add_mechanism("hh");

    std::vector<std::vector<unsigned>> levels;
    levels.push_back({0});

    // Standard mersenne_twister_engine seeded with gid.
    std::mt19937 gen(gid);
    std::uniform_real_distribution<double> dis(0, 1);

    double dend_radius = 0.5; // Diameter of 1 μm for each cable.

    unsigned nsec = 1;
    for (unsigned i=0; i<params.max_depth; ++i) {
        // Branch prob at this level.
        double bp = interp(params.branch_probs, i, params.max_depth);
        // Length at this level.
        double l = interp(params.lengths, i, params.max_depth);
        // Number of compartments at this level.
        unsigned nc = std::round(interp(params.compartments, i, params.max_depth));

        std::vector<unsigned> sec_ids;
        for (unsigned sec: levels[i]) {
            for (unsigned j=0; j<2; ++j) {
                if (dis(gen)<bp) {
                    sec_ids.push_back(nsec++);
                    auto dend = cell.add_cable(sec, arb::section_kind::dendrite, dend_radius, dend_radius, l);
                    dend->set_compartments(nc);
                    dend->add_mechanism("pas");
                    dend->rL = 100;
                }
            }
        }
        if (sec_ids.empty()) {
            break;
        }
        levels.push_back(sec_ids);
    }

    // Add spike threshold detector at the soma.
    cell.add_detector({0,0}, 10);

    // Add a synapse to the mid point of the first dendrite.
    cell.add_synapse({1, 0.5}, "expsyn");

    // Add additional synapses that will not be connected to anything.
    for (unsigned i=1u; i<params.synapses; ++i) {
        cell.add_synapse({1, 0.5}, "expsyn");
    }

    return cell;
}

<commit_msg>fix weights in ring benchmark (#620)<commit_after>/*
 * A miniapp that demonstrates how to make a ring model
 *
 */

#include <fstream>
#include <iomanip>
#include <iostream>

#include <nlohmann/json.hpp>

#include <arbor/assert_macro.hpp>
#include <arbor/common_types.hpp>
#include <arbor/context.hpp>
#include <arbor/load_balance.hpp>
#include <arbor/mc_cell.hpp>
#include <arbor/profile/meter_manager.hpp>
#include <arbor/profile/profiler.hpp>
#include <arbor/simple_sampler.hpp>
#include <arbor/simulation.hpp>
#include <arbor/recipe.hpp>
#include <arbor/version.hpp>

#include <aux/ioutil.hpp>
#include <aux/json_meter.hpp>

#include "parameters.hpp"

#ifdef ARB_MPI_ENABLED
#include <mpi.h>
#include <aux/with_mpi.hpp>
#endif

using arb::cell_gid_type;
using arb::cell_lid_type;
using arb::cell_size_type;
using arb::cell_member_type;
using arb::cell_kind;
using arb::time_type;
using arb::cell_probe_address;

// Writes voltage trace as a json file.
void write_trace_json(const arb::trace_data<double>& trace);

// Generate a cell.
arb::mc_cell branch_cell(arb::cell_gid_type gid, const cell_parameters& params);

class ring_recipe: public arb::recipe {
public:
    ring_recipe(unsigned num_cells, cell_parameters params, unsigned min_delay):
        num_cells_(num_cells),
        cell_params_(params),
        min_delay_(min_delay)
    {}

    cell_size_type num_cells() const override {
        return num_cells_;
    }

    arb::util::unique_any get_cell_description(cell_gid_type gid) const override {
        return branch_cell(gid, cell_params_);
    }

    cell_kind get_cell_kind(cell_gid_type gid) const override {
        return cell_kind::cable1d_neuron;
    }

    // Each cell has one spike detector (at the soma).
    cell_size_type num_sources(cell_gid_type gid) const override {
        return 1;
    }

    // The cell has one target synapse, which will be connected to cell gid-1.
    cell_size_type num_targets(cell_gid_type gid) const override {
        return 1;
    }

    // Each cell has one incoming connection, from cell with gid-1.
    std::vector<arb::cell_connection> connections_on(cell_gid_type gid) const override {
        cell_gid_type src = gid? gid-1: num_cells_-1;
        return {arb::cell_connection({src, 0}, {gid, 0}, event_weight_, min_delay_)};
    }

    // Return one event generator on gid 0. This generates a single event that will
    // kick start the spiking.
    std::vector<arb::event_generator> event_generators(cell_gid_type gid) const override {
        std::vector<arb::event_generator> gens;
        if (!gid) {
            gens.push_back(arb::explicit_generator(arb::pse_vector{{{0, 0}, 1.0, event_weight_}}));
        }
        return gens;
    }

    // There is one probe (for measuring voltage at the soma) on the cell.
    cell_size_type num_probes(cell_gid_type gid)  const override {
        return 1;
    }

    arb::probe_info get_probe(cell_member_type id) const override {
        // Get the appropriate kind for measuring voltage.
        cell_probe_address::probe_kind kind = cell_probe_address::membrane_voltage;
        // Measure at the soma.
        arb::segment_location loc(0, 0.0);

        return arb::probe_info{id, kind, cell_probe_address{loc, kind}};
    }

private:
    cell_size_type num_cells_;
    cell_parameters cell_params_;
    double min_delay_;
    float event_weight_ = 0.05;
};

struct cell_stats {
    using size_type = unsigned;
    size_type ncells = 0;
    size_type nsegs = 0;
    size_type ncomp = 0;

    cell_stats(arb::recipe& r) {
#ifdef ARB_MPI_ENABLED
        int nranks, rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &nranks);
        ncells = r.num_cells();
        size_type cells_per_rank = ncells/nranks;
        size_type b = rank*cells_per_rank;
        size_type e = (rank==nranks-1)? ncells: (rank+1)*cells_per_rank;
        size_type nsegs_tmp = 0;
        size_type ncomp_tmp = 0;
        for (size_type i=b; i<e; ++i) {
            auto c = arb::util::any_cast<arb::mc_cell>(r.get_cell_description(i));
            nsegs_tmp += c.num_segments();
            ncomp_tmp += c.num_compartments();
        }
        MPI_Allreduce(&nsegs_tmp, &nsegs, 1, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD);
        MPI_Allreduce(&ncomp_tmp, &ncomp, 1, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD);
#else
        ncells = r.num_cells();
        for (size_type i=0; i<ncells; ++i) {
            auto c = arb::util::any_cast<arb::mc_cell>(r.get_cell_description(i));
            nsegs += c.num_segments();
            ncomp += c.num_compartments();
        }
#endif
    }

    friend std::ostream& operator<<(std::ostream& o, const cell_stats& s) {
        return o << "cell stats: "
                 << s.ncells << " cells; "
                 << s.nsegs << " segments; "
                 << s.ncomp << " compartments.";
    }
};

int main(int argc, char** argv) {
    try {
        bool root = true;

#ifdef ARB_MPI_ENABLED
        aux::with_mpi guard(argc, argv, false);
        auto context = arb::make_context(arb::proc_allocation(), MPI_COMM_WORLD);
        {
            int rank;
            MPI_Comm_rank(MPI_COMM_WORLD, &rank);
            root = rank==0;
        }
#else
        auto context = arb::make_context();
#endif

#ifdef ARB_PROFILE_ENABLED
        arb::profile::profiler_initialize(context);
#endif

        std::cout << aux::mask_stream(root);

        // Print a banner with information about hardware configuration
        std::cout << "gpu:      " << (has_gpu(context)? "yes": "no") << "\n";
        std::cout << "threads:  " << num_threads(context) << "\n";
        std::cout << "mpi:      " << (has_mpi(context)? "yes": "no") << "\n";
        std::cout << "ranks:    " << num_ranks(context) << "\n" << std::endl;

        auto params = read_options(argc, argv);

        arb::profile::meter_manager meters;
        meters.start(context);

        // Create an instance of our recipe.
        ring_recipe recipe(params.num_cells, params.cell, params.min_delay);
        cell_stats stats(recipe);
        std::cout << stats << "\n";

        auto decomp = arb::partition_load_balance(recipe, context);

        // Construct the model.
        arb::simulation sim(recipe, decomp, context);

        // Set up the probe that will measure voltage in the cell.

        // The id of the only probe on the cell: the cell_member type points to (cell 0, probe 0)
        auto probe_id = cell_member_type{0, 0};
        // The schedule for sampling is 10 samples every 1 ms.
        auto sched = arb::regular_schedule(0.1);
        // This is where the voltage samples will be stored as (time, value) pairs
        arb::trace_data<double> voltage;
        // Now attach the sampler at probe_id, with sampling schedule sched, writing to voltage
        sim.add_sampler(arb::one_probe(probe_id), sched, arb::make_simple_sampler(voltage));

        // Set up recording of spikes to a vector on the root process.
        std::vector<arb::spike> recorded_spikes;
        if (root) {
            sim.set_global_spike_callback(
                [&recorded_spikes](const std::vector<arb::spike>& spikes) {
                    recorded_spikes.insert(recorded_spikes.end(), spikes.begin(), spikes.end());
                });
        }

        meters.checkpoint("model-init", context);

        std::cout << "running simulation" << std::endl;
        // Run the simulation for 100 ms, with time steps of 0.025 ms.
        sim.run(params.duration, 0.025);

        meters.checkpoint("model-run", context);

        auto ns = sim.num_spikes();

        // Write spikes to file
        if (root) {
            std::cout << "\n" << ns << " spikes generated at rate of "
                      << params.duration/ns << " ms between spikes\n";
            std::ofstream fid("spikes.gdf");
            if (!fid.good()) {
                std::cerr << "Warning: unable to open file spikes.gdf for spike output\n";
            }
            else {
                char linebuf[45];
                for (auto spike: recorded_spikes) {
                    auto n = std::snprintf(
                        linebuf, sizeof(linebuf), "%u %.4f\n",
                        unsigned{spike.source.gid}, float(spike.time));
                    fid.write(linebuf, n);
                }
            }
        }

        // Write the samples to a json file.
        if (root) write_trace_json(voltage);

        auto report = arb::profile::make_meter_report(meters, context);
        std::cout << report;
    }
    catch (std::exception& e) {
        std::cerr << "exception caught in ring miniapp:\n" << e.what() << "\n";
        return 1;
    }

    return 0;
}

void write_trace_json(const arb::trace_data<double>& trace) {
    std::string path = "./voltages.json";

    nlohmann::json json;
    json["name"] = "ring demo";
    json["units"] = "mV";
    json["cell"] = "0.0";
    json["probe"] = "0";

    auto& jt = json["data"]["time"];
    auto& jy = json["data"]["voltage"];

    for (const auto& sample: trace) {
        jt.push_back(sample.t);
        jy.push_back(sample.v);
    }

    std::ofstream file(path);
    file << std::setw(1) << json << "\n";
}

// Helper used to interpolate in branch_cell.
template <typename T>
double interp(const std::array<T,2>& r, unsigned i, unsigned n) {
    double p = i * 1./(n-1);
    double r0 = r[0];
    double r1 = r[1];
    return r[0] + p*(r1-r0);
}

arb::mc_cell branch_cell(arb::cell_gid_type gid, const cell_parameters& params) {
    arb::mc_cell cell;

    // Add soma.
    auto soma = cell.add_soma(12.6157/2.0); // For area of 500 μm².
    soma->rL = 100;
    soma->add_mechanism("hh");

    std::vector<std::vector<unsigned>> levels;
    levels.push_back({0});

    // Standard mersenne_twister_engine seeded with gid.
    std::mt19937 gen(gid);
    std::uniform_real_distribution<double> dis(0, 1);

    double dend_radius = 0.5; // Diameter of 1 μm for each cable.

    unsigned nsec = 1;
    for (unsigned i=0; i<params.max_depth; ++i) {
        // Branch prob at this level.
        double bp = interp(params.branch_probs, i, params.max_depth);
        // Length at this level.
        double l = interp(params.lengths, i, params.max_depth);
        // Number of compartments at this level.
        unsigned nc = std::round(interp(params.compartments, i, params.max_depth));

        std::vector<unsigned> sec_ids;
        for (unsigned sec: levels[i]) {
            for (unsigned j=0; j<2; ++j) {
                if (dis(gen)<bp) {
                    sec_ids.push_back(nsec++);
                    auto dend = cell.add_cable(sec, arb::section_kind::dendrite, dend_radius, dend_radius, l);
                    dend->set_compartments(nc);
                    dend->add_mechanism("pas");
                    dend->rL = 100;
                }
            }
        }
        if (sec_ids.empty()) {
            break;
        }
        levels.push_back(sec_ids);
    }

    // Add spike threshold detector at the soma.
    cell.add_detector({0,0}, 10);

    // Add a synapse to the mid point of the first dendrite.
    cell.add_synapse({1, 0.5}, "expsyn");

    // Add additional synapses that will not be connected to anything.
    for (unsigned i=1u; i<params.synapses; ++i) {
        cell.add_synapse({1, 0.5}, "expsyn");
    }

    return cell;
}

<|endoftext|>


<commit_before>/*
 *  Created on: Nov 26, 2014
 *      Author: Benedikt Wolters
 */
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE utility/random
#include <boost/test/unit_test.hpp>

#include <geneial/utility/Random.h>

BOOST_AUTO_TEST_SUITE( RandomSuite )

BOOST_AUTO_TEST_CASE( valid_values_ranges )
{
	using namespace GeneticLibrary::Utility;
	bool myRandBool = Random::instance()->generateBit();
	BOOST_CHECK( myRandBool == true || myRandBool == false);
}

//Make TEST_INT_UNIFORM_RUNS, see whether randomness divergates by TEST_INT_UNIFORM_TOLERANCE
#define TEST_INT_UNIFORM_RUNS 1000000
#define TEST_INT_UNIFORM_SLOTS 10
#define TEST_INT_UNIFORM_TOLERANCE 0.01f

BOOST_AUTO_TEST_CASE( int_uniform )
{
	using namespace GeneticLibrary::Utility;

	int occurrences[TEST_INT_UNIFORM_SLOTS];

	for(int i=0; i<(TEST_INT_UNIFORM_SLOTS-1); i++)
	{
		occurrences[i] = 0;
	}

	for(int i=1;i<TEST_INT_UNIFORM_RUNS;i++){
		occurrences[Random::instance()->generateInt(0,9)]++;
	}

	for(int i=0; i<(TEST_INT_UNIFORM_SLOTS-1); i++)
	{

		BOOST_CHECK_MESSAGE(
				((float) occurrences[i] / (float) TEST_INT_UNIFORM_RUNS)
					<
				((float) TEST_INT_UNIFORM_RUNS / (float) TEST_INT_UNIFORM_SLOTS) / (float) TEST_INT_UNIFORM_RUNS
				+ (float) TEST_INT_UNIFORM_TOLERANCE,
				"uniform failed for " << i << " with " << (float) occurrences[i] / (float) TEST_INT_UNIFORM_RUNS);
	}
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>expanded/refined random test<commit_after>/*
 *  Created on: Nov 26, 2014
 *      Author: Benedikt Wolters
 */
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE utility/random
#include <boost/test/unit_test.hpp>

#include <geneial/utility/Random.h>
using namespace GeneticLibrary::Utility;

BOOST_AUTO_TEST_SUITE( RandomSuite )

BOOST_AUTO_TEST_CASE( valid_values_ranges_bool )
{
	bool myRandBool = Random::instance()->generateBit();
	BOOST_CHECK( myRandBool == true || myRandBool == false);
}

#define TEST_INT_VALUERANGE_RUNS 1000
BOOST_AUTO_TEST_CASE( valid_values_ranges_int )
{
	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const int result = Random::instance()->generateInt(0,100);
		BOOST_CHECK( result >= 0 && result <= 100);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const int result = Random::instance()->generateInt(-100,0);
		BOOST_CHECK( result >= -100 && result <= 0);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const int result = Random::instance()->generateInt(-100,100);
		BOOST_CHECK( result >= -100 && result <= 100);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const float result = Random::instance()->generateFloat(0,100);
		BOOST_CHECK( result >= 0 && result <= 100);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const float result = Random::instance()->generateFloat(-100,0);
		BOOST_CHECK( result >= -100 && result <= 0);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const float result = Random::instance()->generateFloat(-100,100);
		BOOST_CHECK( result >= -100 && result <= 100);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const double result = Random::instance()->generateDouble(0,100);
		BOOST_CHECK( result >= 0 && result <= 100);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const double result = Random::instance()->generateDouble(-100,0);
		BOOST_CHECK( result >= -100 && result <= 0);
	}

	for(int i=1;i<TEST_INT_VALUERANGE_RUNS;i++){
		const double result = Random::instance()->generateDouble(-100,100);
		BOOST_CHECK( result >= -100 && result <= 100);
	}
}

BOOST_AUTO_TEST_CASE( difference )
{
	double myRand1D= Random::instance()->generateDouble();
	double myRand2D= Random::instance()->generateDouble();
	BOOST_CHECK( myRand1D != myRand2D);

	float myRand1F= Random::instance()->generateFloat();
	float myRand2F= Random::instance()->generateFloat();
	BOOST_CHECK( myRand1F != myRand2F);

	int myRand1I= Random::instance()->generateInt();
	int myRand2I= Random::instance()->generateInt();
	BOOST_CHECK( myRand1I != myRand2I);
}

//Make TEST_INT_UNIFORM_RUNS, see whether randomness divergates by TEST_INT_UNIFORM_TOLERANCE
#define TEST_INT_UNIFORM_RUNS 1e6
#define TEST_INT_UNIFORM_SLOTS 10
#define TEST_INT_UNIFORM_TOLERANCE 0.001f

BOOST_AUTO_TEST_CASE( int_uniform )
{

	BOOST_TEST_MESSAGE("TEST_INT_UNIFORM_RUNS: " << TEST_INT_UNIFORM_RUNS);
	BOOST_TEST_MESSAGE("TEST_INT_UNIFORM_SLOTS: " << TEST_INT_UNIFORM_SLOTS);
	BOOST_TEST_MESSAGE("TEST_INT_UNIFORM_TOLERANCE: " << TEST_INT_UNIFORM_TOLERANCE);

	int occurrences[TEST_INT_UNIFORM_SLOTS];

	for(int i=0; i<(TEST_INT_UNIFORM_SLOTS); i++)
	{
		occurrences[i] = 0;
	}

	for(int i=1;i<TEST_INT_UNIFORM_RUNS;i++){
		occurrences[Random::instance()->generateInt(0,TEST_INT_UNIFORM_SLOTS-1)]++;
	}

	BOOST_TEST_MESSAGE("Int Distribution: ");
	for(int i=0; i<(TEST_INT_UNIFORM_SLOTS); i++)
	{
		BOOST_TEST_MESSAGE(i << " " << std::string((int)100* ((float) occurrences[i] / (float) TEST_INT_UNIFORM_RUNS), '+') );
	}

	for(int i=0; i<(TEST_INT_UNIFORM_SLOTS); i++)
	{
		BOOST_CHECK_MESSAGE(
				((float) occurrences[i] / (float) TEST_INT_UNIFORM_RUNS)
					<
				((float) TEST_INT_UNIFORM_RUNS / (float) TEST_INT_UNIFORM_SLOTS) / (float) TEST_INT_UNIFORM_RUNS
				+ (float) TEST_INT_UNIFORM_TOLERANCE,
				"uniform failed for " << i << " with " << (float) occurrences[i] / (float) TEST_INT_UNIFORM_RUNS);
	}
}
#define TEST_DOUBLE_UNIFORM_RUNS 1e6
#define TEST_DOUBLE_UNIFORM_SLOTS 10
#define TEST_DOUBLE_UNIFORM_TOLERANCE 0.001f
#define TEST_DOUBLE_BOUND_TOLERANCE 0.00001f
BOOST_AUTO_TEST_CASE( double_uniform )
{

	BOOST_TEST_MESSAGE("TEST_DOUBLE_UNIFORM_RUNS: " << TEST_DOUBLE_UNIFORM_RUNS);
	BOOST_TEST_MESSAGE("TEST_DOUBLE_UNIFORM_SLOTS: " << TEST_DOUBLE_UNIFORM_SLOTS);
	BOOST_TEST_MESSAGE("TEST_DOUBLE_UNIFORM_TOLERANCE: " << TEST_DOUBLE_UNIFORM_TOLERANCE);

	int occurrences[TEST_DOUBLE_UNIFORM_SLOTS];

	for(int i=0; i<(TEST_DOUBLE_UNIFORM_SLOTS); i++)
	{
		occurrences[i] = 0;
	}

	for(int i=1;i<TEST_DOUBLE_UNIFORM_RUNS;i++){
		const int val = (int)Random::instance()->generateDouble(0,TEST_DOUBLE_UNIFORM_SLOTS-TEST_DOUBLE_BOUND_TOLERANCE);
		occurrences[val]++;
	}

	BOOST_TEST_MESSAGE("Double Distribution: ");
	for(int i=0; i<(TEST_DOUBLE_UNIFORM_SLOTS); i++)
	{
		BOOST_TEST_MESSAGE(i << " " << std::string((int)100* ((float) occurrences[i] / (float) TEST_DOUBLE_UNIFORM_RUNS), '+') );
	}

	for(int i=0; i<(TEST_DOUBLE_UNIFORM_SLOTS); i++)
	{
		BOOST_CHECK_MESSAGE(
				((float) occurrences[i] / (float) TEST_DOUBLE_UNIFORM_RUNS)
					<
				((float) TEST_DOUBLE_UNIFORM_RUNS / (float) TEST_DOUBLE_UNIFORM_SLOTS) / (float) TEST_DOUBLE_UNIFORM_RUNS
				+ (float) TEST_DOUBLE_UNIFORM_TOLERANCE,
				"uniform failed for " << i << " with " << (float) occurrences[i] / (float) TEST_DOUBLE_UNIFORM_RUNS);
	}
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>