<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "GosmoreRunner.h"

#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "routing/RouteSkeleton.h"
#include "GeoDataDocument.h"
#include "GeoDataExtendedData.h"

#include <QtCore/QProcess>
#include <QtCore/QMap>

namespace Marble
{

class GosmoreRunnerPrivate
{
public:
    QFileInfo m_gosmoreMapFile;

    QByteArray retrieveWaypoints( const QString &query ) const;

    GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints ) const;

    GeoDataLineString parseGosmoreOutput( const QByteArray &content ) const;

    void merge( GeoDataLineString* one, const GeoDataLineString& two ) const;

    /** Static to share the cache among all instances */
    static QMap<QString, QByteArray> m_partialRoutes;
};

QMap<QString, QByteArray> GosmoreRunnerPrivate::m_partialRoutes;

void GosmoreRunnerPrivate::merge( GeoDataLineString* one, const GeoDataLineString& two ) const
{
    Q_ASSERT( one );

    QVector<GeoDataCoordinates>::const_iterator iter = two.constBegin();
    for( ; iter != two.constEnd(); ++iter ) {
        /** @todo: It might be needed to cut off some points at the start or end */
        one->append( *iter );
    }
}

QByteArray GosmoreRunnerPrivate::retrieveWaypoints( const QString &query ) const
{
    if ( m_partialRoutes.contains(query) ) {
        return m_partialRoutes[query];
    }

    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert("QUERY_STRING", query);
    env.insert("LC_ALL", "C");
    QProcess gosmore;
    gosmore.setProcessEnvironment(env);

    gosmore.start("gosmore", QStringList() << m_gosmoreMapFile.absoluteFilePath() );
    if (!gosmore.waitForStarted(5000)) {
        mDebug() << "Couldn't start gosmore from the current PATH. Install it to retrieve routing results from gosmore.";
        return QByteArray();
    }

    if ( gosmore.waitForFinished(15000) ) {
        m_partialRoutes[query] = gosmore.readAllStandardOutput();
        return m_partialRoutes[query];
    }
    else {
        mDebug() << "Couldn't stop gosmore";
    }

    return QByteArray();
}

GeoDataLineString GosmoreRunnerPrivate::parseGosmoreOutput( const QByteArray &content ) const
{
    GeoDataLineString routeWaypoints;

    QStringList lines = QString::fromLocal8Bit( content ).split( '\r' );
    foreach( const QString &line, lines ) {
        QStringList fields = line.split(',');
        if (fields.size() >= 5) {
            qreal lon = fields.at(1).toDouble();
            qreal lat = fields.at(0).toDouble();
            GeoDataCoordinates coordinates( lon, lat, 0.0, GeoDataCoordinates::Degree );
            routeWaypoints.append( coordinates );
        }
    }

    return routeWaypoints;
}

GeoDataDocument* GosmoreRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints ) const
{
    if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
        return 0;
    }

    GeoDataDocument* result = new GeoDataDocument();
    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName( "Route" );
    routePlacemark->setGeometry( routeWaypoints );
    result->append( routePlacemark );

    QString name = "%1 %2 (Gosmore)";
    QString unit = "m";
    qreal length = routeWaypoints->length( EARTH_RADIUS );
    if (length >= 1000) {
        length /= 1000.0;
        unit = "km";
    }
    result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
    return result;
}

GosmoreRunner::GosmoreRunner( QObject *parent ) :
        MarbleAbstractRunner( parent ),
        d( new GosmoreRunnerPrivate )
{
    // Check installation
    QDir mapDir( MarbleDirs::localPath() + "/maps/earth/gosmore/" );
    d->m_gosmoreMapFile = QFileInfo ( mapDir, "gosmore.pak" );
}

GosmoreRunner::~GosmoreRunner()
{
    delete d;
}

GeoDataFeature::GeoDataVisualCategory GosmoreRunner::category() const
{
    return GeoDataFeature::OsmSite;
}

void GosmoreRunner::retrieveRoute( RouteSkeleton *route )
{
    if ( !d->m_gosmoreMapFile.exists() )
    {
        emit routeCalculated( 0 );
        return;
    }

    GeoDataLineString* wayPoints = new GeoDataLineString;

    for( int i=0; i<route->size()-1; ++i )
    {
        QString queryString = "flat=%1&flon=%2&tlat=%3&tlon=%4&fastest=1&v=motorcar";
        GeoDataCoordinates source = route->at(i);
        double fLon = source.longitude( GeoDataCoordinates::Degree );
        double fLat = source.latitude( GeoDataCoordinates::Degree );
        queryString = queryString.arg(fLat, 0, 'f', 8).arg(fLon, 0, 'f', 8);
        GeoDataCoordinates destination = route->at(i+1);
        double tLon = destination.longitude( GeoDataCoordinates::Degree );
        double tLat = destination.latitude( GeoDataCoordinates::Degree );
        queryString = queryString.arg(tLat, 0, 'f', 8).arg(tLon, 0, 'f', 8);

        d->merge( wayPoints, d->parseGosmoreOutput( d->retrieveWaypoints( queryString ) ) );
    }

    GeoDataDocument* result = d->createDocument( wayPoints );
    emit routeCalculated( result );
}

void GosmoreRunner::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    QString queryString = "flat=%1&flon=%2&tlat=%1&tlon=%2&fastest=1&v=motorcar";
    double lon = coordinates.longitude( GeoDataCoordinates::Degree );
    double lat = coordinates.latitude( GeoDataCoordinates::Degree );
    queryString = queryString.arg( lat, 0, 'f', 8).arg(lon, 0, 'f', 8 );
    QByteArray output = d->retrieveWaypoints( queryString );

    GeoDataPlacemark placemark;
    placemark.setCoordinate( GeoDataPoint( coordinates ) );

    QStringList lines = QString::fromUtf8( output ).split( '\r' );
    if ( lines.size() > 2 ) {
        QStringList fields = lines.at( lines.size()-2 ).split(',');
        if ( fields.size() >= 5 ) {
            QString road = fields.last();
            placemark.setAddress( road );
            GeoDataExtendedData extendedData;
            GeoDataData data;
            data.setValue( road );
            extendedData.addValue( "road", data );
            placemark.setExtendedData( extendedData );
        }
    }

    emit reverseGeocodingFinished( coordinates, placemark );
}

} // namespace Marble
<commit_msg>Remove trailing whitespace in reverse geocoding results.<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "GosmoreRunner.h"

#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "routing/RouteSkeleton.h"
#include "GeoDataDocument.h"
#include "GeoDataExtendedData.h"

#include <QtCore/QProcess>
#include <QtCore/QMap>

namespace Marble
{

class GosmoreRunnerPrivate
{
public:
    QFileInfo m_gosmoreMapFile;

    QByteArray retrieveWaypoints( const QString &query ) const;

    GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints ) const;

    GeoDataLineString parseGosmoreOutput( const QByteArray &content ) const;

    void merge( GeoDataLineString* one, const GeoDataLineString& two ) const;

    /** Static to share the cache among all instances */
    static QMap<QString, QByteArray> m_partialRoutes;
};

QMap<QString, QByteArray> GosmoreRunnerPrivate::m_partialRoutes;

void GosmoreRunnerPrivate::merge( GeoDataLineString* one, const GeoDataLineString& two ) const
{
    Q_ASSERT( one );

    QVector<GeoDataCoordinates>::const_iterator iter = two.constBegin();
    for( ; iter != two.constEnd(); ++iter ) {
        /** @todo: It might be needed to cut off some points at the start or end */
        one->append( *iter );
    }
}

QByteArray GosmoreRunnerPrivate::retrieveWaypoints( const QString &query ) const
{
    if ( m_partialRoutes.contains(query) ) {
        return m_partialRoutes[query];
    }

    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert("QUERY_STRING", query);
    env.insert("LC_ALL", "C");
    QProcess gosmore;
    gosmore.setProcessEnvironment(env);

    gosmore.start("gosmore", QStringList() << m_gosmoreMapFile.absoluteFilePath() );
    if (!gosmore.waitForStarted(5000)) {
        mDebug() << "Couldn't start gosmore from the current PATH. Install it to retrieve routing results from gosmore.";
        return QByteArray();
    }

    if ( gosmore.waitForFinished(15000) ) {
        m_partialRoutes[query] = gosmore.readAllStandardOutput();
        return m_partialRoutes[query];
    }
    else {
        mDebug() << "Couldn't stop gosmore";
    }

    return QByteArray();
}

GeoDataLineString GosmoreRunnerPrivate::parseGosmoreOutput( const QByteArray &content ) const
{
    GeoDataLineString routeWaypoints;

    QStringList lines = QString::fromLocal8Bit( content ).split( '\r' );
    foreach( const QString &line, lines ) {
        QStringList fields = line.split(',');
        if (fields.size() >= 5) {
            qreal lon = fields.at(1).toDouble();
            qreal lat = fields.at(0).toDouble();
            GeoDataCoordinates coordinates( lon, lat, 0.0, GeoDataCoordinates::Degree );
            routeWaypoints.append( coordinates );
        }
    }

    return routeWaypoints;
}

GeoDataDocument* GosmoreRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints ) const
{
    if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
        return 0;
    }

    GeoDataDocument* result = new GeoDataDocument();
    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName( "Route" );
    routePlacemark->setGeometry( routeWaypoints );
    result->append( routePlacemark );

    QString name = "%1 %2 (Gosmore)";
    QString unit = "m";
    qreal length = routeWaypoints->length( EARTH_RADIUS );
    if (length >= 1000) {
        length /= 1000.0;
        unit = "km";
    }
    result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
    return result;
}

GosmoreRunner::GosmoreRunner( QObject *parent ) :
        MarbleAbstractRunner( parent ),
        d( new GosmoreRunnerPrivate )
{
    // Check installation
    QDir mapDir( MarbleDirs::localPath() + "/maps/earth/gosmore/" );
    d->m_gosmoreMapFile = QFileInfo ( mapDir, "gosmore.pak" );
}

GosmoreRunner::~GosmoreRunner()
{
    delete d;
}

GeoDataFeature::GeoDataVisualCategory GosmoreRunner::category() const
{
    return GeoDataFeature::OsmSite;
}

void GosmoreRunner::retrieveRoute( RouteSkeleton *route )
{
    if ( !d->m_gosmoreMapFile.exists() )
    {
        emit routeCalculated( 0 );
        return;
    }

    GeoDataLineString* wayPoints = new GeoDataLineString;

    for( int i=0; i<route->size()-1; ++i )
    {
        QString queryString = "flat=%1&flon=%2&tlat=%3&tlon=%4&fastest=1&v=motorcar";
        GeoDataCoordinates source = route->at(i);
        double fLon = source.longitude( GeoDataCoordinates::Degree );
        double fLat = source.latitude( GeoDataCoordinates::Degree );
        queryString = queryString.arg(fLat, 0, 'f', 8).arg(fLon, 0, 'f', 8);
        GeoDataCoordinates destination = route->at(i+1);
        double tLon = destination.longitude( GeoDataCoordinates::Degree );
        double tLat = destination.latitude( GeoDataCoordinates::Degree );
        queryString = queryString.arg(tLat, 0, 'f', 8).arg(tLon, 0, 'f', 8);

        d->merge( wayPoints, d->parseGosmoreOutput( d->retrieveWaypoints( queryString ) ) );
    }

    GeoDataDocument* result = d->createDocument( wayPoints );
    emit routeCalculated( result );
}

void GosmoreRunner::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    QString queryString = "flat=%1&flon=%2&tlat=%1&tlon=%2&fastest=1&v=motorcar";
    double lon = coordinates.longitude( GeoDataCoordinates::Degree );
    double lat = coordinates.latitude( GeoDataCoordinates::Degree );
    queryString = queryString.arg( lat, 0, 'f', 8).arg(lon, 0, 'f', 8 );
    QByteArray output = d->retrieveWaypoints( queryString );

    GeoDataPlacemark placemark;
    placemark.setCoordinate( GeoDataPoint( coordinates ) );

    QStringList lines = QString::fromUtf8( output ).split( '\r' );
    if ( lines.size() > 2 ) {
        QStringList fields = lines.at( lines.size()-2 ).split(',');
        if ( fields.size() >= 5 ) {
            QString road = fields.last().trimmed();
            placemark.setAddress( road );
            GeoDataExtendedData extendedData;
            GeoDataData data;
            data.setValue( road );
            extendedData.addValue( "road", data );
            placemark.setExtendedData( extendedData );
        }
    }

    emit reverseGeocodingFinished( coordinates, placemark );
}

} // namespace Marble
<|endoftext|>


<commit_before>#include "AnimationBlender.h"
#include <Scene/SceneNode.h>

namespace DEM::Anim
{

// NB: this invalidates all current transforms at least for now
void CAnimationBlender::Initialize(U8 SourceCount)
{
	_SourceInfo.resize(SourceCount);
	_Nodes.clear();
	_Transforms.clear();
	_ChannelMasks.clear();

	// All sources initially have the same priority, order is not important
	_SourcesByPriority.resize(SourceCount);
	for (size_t i = 0; i < SourceCount; ++i)
		_SourcesByPriority[i] = i;
}
//---------------------------------------------------------------------

void CAnimationBlender::Apply()
{
	const auto PortCount = _Nodes.size();
	const auto SourceCount = _SourceInfo.size();
	if (!PortCount || !SourceCount) return;

	for (UPTR Port = 0; Port < PortCount; ++Port)
	{
		Math::CTransformSRT FinalTfm;
		U8 FinalMask = 0;
		float ScaleWeights = 0.f;
		float RotationWeights = 0.f;
		float TranslationWeights = 0.f;

		const auto Offset = Port * SourceCount;

		for (const auto& SourceIndex : _SourcesByPriority)
		{
			const float SourceWeight = _SourceInfo[SourceIndex].Weight;
			if (SourceWeight <= 0.f) return;

			const auto CurrTfm = _Transforms[Offset + SourceIndex];
			const U8 ChannelMask = _ChannelMasks[Offset + SourceIndex];

			if ((ChannelMask & Scene::Tfm_Scaling) && ScaleWeights < 1.f)
			{
				const float Weight = std::min(SourceWeight, 1.f - ScaleWeights);

				// Scale is 1.f by default. To blend correctly, we must reset it to zero before applying the first source.
				if (FinalMask & Scene::Tfm_Scaling)
					FinalTfm.Scale += CurrTfm.Scale * Weight;
				else
					FinalTfm.Scale = CurrTfm.Scale * Weight;

				FinalMask |= Scene::Tfm_Scaling;
				ScaleWeights += Weight;
			}

			if ((ChannelMask & Scene::Tfm_Rotation) && RotationWeights < 1.f)
			{
				const float Weight = std::min(SourceWeight, 1.f - RotationWeights);

				// TODO: check this hardcore stuff for multiple quaternion blending:
				// https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20070017872.pdf
				if (FinalMask & Scene::Tfm_Rotation)
				{
					quaternion Q;
					Q.slerp(quaternion::Identity, CurrTfm.Rotation, Weight);
					FinalTfm.Rotation *= Q;
				}
				else
				{
					FinalTfm.Rotation.slerp(quaternion::Identity, CurrTfm.Rotation, Weight);
				}

				FinalMask |= Scene::Tfm_Rotation;
				RotationWeights += Weight;
			}

			if ((ChannelMask & Scene::Tfm_Translation) && TranslationWeights < 1.f)
			{
				const float Weight = std::min(SourceWeight, 1.f - TranslationWeights);
				FinalTfm.Translation += CurrTfm.Translation * Weight;
				FinalMask |= Scene::Tfm_Translation;
				TranslationWeights += Weight;
			}
		}

		// Apply accumulated transform

		if (FinalMask & Scene::Tfm_Scaling)
			_Nodes[Port]->SetScale(FinalTfm.Scale);

		if (FinalMask & Scene::Tfm_Rotation)
		{
			if (RotationWeights < 1.f) FinalTfm.Rotation.normalize();
			_Nodes[Port]->SetRotation(FinalTfm.Rotation);
		}

		if (FinalMask & Scene::Tfm_Translation)
			_Nodes[Port]->SetPosition(FinalTfm.Translation);
	}

	std::memset(_ChannelMasks.data(), 0, _ChannelMasks.size());
}
//---------------------------------------------------------------------

void CAnimationBlender::SetPriority(U8 Source, U32 Priority)
{
	if (Source < _SourceInfo.size() && _SourceInfo[Source].Priority != Priority)
	{
		_SourceInfo[Source].Priority = Priority;

		std::sort(_SourcesByPriority.begin(), _SourcesByPriority.end(), [this](UPTR a, UPTR b)
		{
			return _SourceInfo[a].Priority > _SourceInfo[b].Priority;
		});
	}
}
//---------------------------------------------------------------------

// NB: slow operation
U32 CAnimationBlender::GetOrCreateNodePort(Scene::CSceneNode* pNode)
{
	if (!pNode || _Nodes.size() >= std::numeric_limits<U32>().max())
		return InvalidPort;

	const auto PortCount = _Nodes.size();
	for (UPTR Port = 0; Port < PortCount; ++Port)
		if (_Nodes[Port] == pNode)
			return Port;

	_Nodes.push_back(pNode);
	_Transforms.resize(_Transforms.size() + _SourceInfo.size());
	_ChannelMasks.resize(_ChannelMasks.size() + _SourceInfo.size());

	return static_cast<U32>(_Nodes.size() - 1);
}
//---------------------------------------------------------------------

}
<commit_msg>Zero weight blending fixed<commit_after>#include "AnimationBlender.h"
#include <Scene/SceneNode.h>

namespace DEM::Anim
{

// NB: this invalidates all current transforms at least for now
void CAnimationBlender::Initialize(U8 SourceCount)
{
	_SourceInfo.resize(SourceCount);
	_Nodes.clear();
	_Transforms.clear();
	_ChannelMasks.clear();

	// All sources initially have the same priority, order is not important
	_SourcesByPriority.resize(SourceCount);
	for (size_t i = 0; i < SourceCount; ++i)
		_SourcesByPriority[i] = i;
}
//---------------------------------------------------------------------

void CAnimationBlender::Apply()
{
	const auto PortCount = _Nodes.size();
	const auto SourceCount = _SourceInfo.size();
	if (!PortCount || !SourceCount) return;

	for (UPTR Port = 0; Port < PortCount; ++Port)
	{
		Math::CTransformSRT FinalTfm;
		U8 FinalMask = 0;
		float ScaleWeights = 0.f;
		float RotationWeights = 0.f;
		float TranslationWeights = 0.f;

		const auto Offset = Port * SourceCount;

		for (const auto& SourceIndex : _SourcesByPriority)
		{
			const float SourceWeight = _SourceInfo[SourceIndex].Weight;
			if (SourceWeight <= 0.f) continue;

			const auto CurrTfm = _Transforms[Offset + SourceIndex];
			const U8 ChannelMask = _ChannelMasks[Offset + SourceIndex];

			if ((ChannelMask & Scene::Tfm_Scaling) && ScaleWeights < 1.f)
			{
				const float Weight = std::min(SourceWeight, 1.f - ScaleWeights);

				// Scale is 1.f by default. To blend correctly, we must reset it to zero before applying the first source.
				if (FinalMask & Scene::Tfm_Scaling)
					FinalTfm.Scale += CurrTfm.Scale * Weight;
				else
					FinalTfm.Scale = CurrTfm.Scale * Weight;

				FinalMask |= Scene::Tfm_Scaling;
				ScaleWeights += Weight;
			}

			if ((ChannelMask & Scene::Tfm_Rotation) && RotationWeights < 1.f)
			{
				const float Weight = std::min(SourceWeight, 1.f - RotationWeights);

				// TODO: check this hardcore stuff for multiple quaternion blending:
				// https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20070017872.pdf
				if (FinalMask & Scene::Tfm_Rotation)
				{
					quaternion Q;
					Q.slerp(quaternion::Identity, CurrTfm.Rotation, Weight);
					FinalTfm.Rotation *= Q;
				}
				else
				{
					FinalTfm.Rotation.slerp(quaternion::Identity, CurrTfm.Rotation, Weight);
				}

				FinalMask |= Scene::Tfm_Rotation;
				RotationWeights += Weight;
			}

			if ((ChannelMask & Scene::Tfm_Translation) && TranslationWeights < 1.f)
			{
				const float Weight = std::min(SourceWeight, 1.f - TranslationWeights);
				FinalTfm.Translation += CurrTfm.Translation * Weight;
				FinalMask |= Scene::Tfm_Translation;
				TranslationWeights += Weight;
			}
		}

		// Apply accumulated transform

		if (FinalMask & Scene::Tfm_Scaling)
			_Nodes[Port]->SetScale(FinalTfm.Scale);

		if (FinalMask & Scene::Tfm_Rotation)
		{
			if (RotationWeights < 1.f) FinalTfm.Rotation.normalize();
			_Nodes[Port]->SetRotation(FinalTfm.Rotation);
		}

		if (FinalMask & Scene::Tfm_Translation)
			_Nodes[Port]->SetPosition(FinalTfm.Translation);
	}

	std::memset(_ChannelMasks.data(), 0, _ChannelMasks.size());
}
//---------------------------------------------------------------------

void CAnimationBlender::SetPriority(U8 Source, U32 Priority)
{
	if (Source < _SourceInfo.size() && _SourceInfo[Source].Priority != Priority)
	{
		_SourceInfo[Source].Priority = Priority;

		std::sort(_SourcesByPriority.begin(), _SourcesByPriority.end(), [this](UPTR a, UPTR b)
		{
			return _SourceInfo[a].Priority > _SourceInfo[b].Priority;
		});
	}
}
//---------------------------------------------------------------------

// NB: slow operation
U32 CAnimationBlender::GetOrCreateNodePort(Scene::CSceneNode* pNode)
{
	if (!pNode || _Nodes.size() >= std::numeric_limits<U32>().max())
		return InvalidPort;

	const auto PortCount = _Nodes.size();
	for (UPTR Port = 0; Port < PortCount; ++Port)
		if (_Nodes[Port] == pNode)
			return Port;

	_Nodes.push_back(pNode);
	_Transforms.resize(_Transforms.size() + _SourceInfo.size());
	_ChannelMasks.resize(_ChannelMasks.size() + _SourceInfo.size());

	return static_cast<U32>(_Nodes.size() - 1);
}
//---------------------------------------------------------------------

}
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 * ginlogic.c
 *	  routines for performing binary- and ternary-logic consistent checks.
 *
 * A GIN operator___ class___ can provide a boolean or ternary consistent
 * function, or both.  This file provides both boolean and ternary
 * interfaces to the rest of the GIN code, even if only one of them is
 * implemented by the opclass.
 *
 * Providing a boolean interface when the opclass implements only the
 * ternary function is straightforward - just call the ternary function
 * with the check-array as is, and map the GIN_TRUE, GIN_FALSE, GIN_MAYBE
 * return codes to TRUE, FALSE and TRUE+recheck, respectively.  Providing
 * a ternary interface when the opclass only implements a boolean function
 * is implemented by calling the boolean function many times, with all the
 * MAYBE arguments set to all combinations of TRUE and FALSE (up to a
 * certain number of MAYBE arguments).
 *
 * (A boolean function is enough to determine if an item matches, but a
 * GIN scan can apply various optimizations if it can determine that an
 * item matches or doesn't match, even if it doesn't know if some of the
 * keys are present or not.  That's what the ternary consistent function
 * is used for.)
 *
 *
 * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *			src/backend/access/gin/ginlogic.c
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/gin_private.h"
#include "access/reloptions.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "storage/indexfsm.h"
#include "storage/lmgr.h"

/*
 * Maximum number of MAYBE inputs that shimTriConsistentFn will try to
 * resolve by calling all combinations.
 */
#define MAX_MAYBE_ENTRIES	4

/*
 * Dummy consistent functions for an EVERYTHING key.  Just claim it matches.
 */
static bool
trueConsistentFn(GinScanKey key)
{
	key->recheckCurItem = false;
	return true;
}
static GinTernaryValue
trueTriConsistentFn(GinScanKey key)
{
	return GIN_TRUE;
}

/*
 * A helper function for calling a regular, binary logic, consistent function.
 */
static bool
directBoolConsistentFn(GinScanKey key)
{
	/*
	 * Initialize recheckCurItem in case the consistentFn doesn't know it
	 * should set it.  The safe assumption in that case is to force recheck.
	 */
	key->recheckCurItem = true;

	return DatumGetBool(FunctionCall8Coll(key->consistentFmgrInfo,
										  key->collation,
										  PointerGetDatum(key->entryRes),
										  UInt16GetDatum(key->strategy),
										  key->query,
										  UInt32GetDatum(key->nuserentries),
										  PointerGetDatum(key->extra_data),
									   PointerGetDatum(&key->recheckCurItem),
										  PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
}

/*
 * A helper function for calling a native ternary logic consistent function.
 */
static GinTernaryValue
directTriConsistentFn(GinScanKey key)
{
	return DatumGetGinTernaryValue(FunctionCall7Coll(
												  key->triConsistentFmgrInfo,
													 key->collation,
											  PointerGetDatum(key->entryRes),
											   UInt16GetDatum(key->strategy),
													 key->query,
										   UInt32GetDatum(key->nuserentries),
											PointerGetDatum(key->extra_data),
										   PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
}

/*
 * This function implements a binary logic consistency check, using a ternary
 * logic consistent function provided by the opclass. GIN_MAYBE return value
 * is interpreted as true with recheck flag.
 */
static bool
shimBoolConsistentFn(GinScanKey key)
{
	GinTernaryValue result;

	result = DatumGetGinTernaryValue(FunctionCall7Coll(
												  key->triConsistentFmgrInfo,
													   key->collation,
											  PointerGetDatum(key->entryRes),
											   UInt16GetDatum(key->strategy),
													   key->query,
										   UInt32GetDatum(key->nuserentries),
											PointerGetDatum(key->extra_data),
										   PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
	if (result == GIN_MAYBE)
	{
		key->recheckCurItem = true;
		return true;
	}
	else
	{
		key->recheckCurItem = false;
		return result;
	}
}

/*
 * This function implements a tri-state consistency check, using a boolean
 * consistent function provided by the opclass.
 *
 * Our strategy is to call consistentFn with MAYBE inputs replaced with every
 * combination of TRUE/FALSE. If consistentFn returns the same value for every
 * combination, that's the overall result. Otherwise, return MAYBE. Testing
 * every combination is O(n^2), so this is only feasible for a small number of
 * MAYBE inputs.
 *
 * NB: This function modifies the key->entryRes array!
 */
static GinTernaryValue
shimTriConsistentFn(GinScanKey key)
{
	int			nmaybe;
	int			maybeEntries[MAX_MAYBE_ENTRIES];
	int			i;
	bool		boolResult;
	bool		recheck = false;
	GinTernaryValue curResult;

	/*
	 * Count how many MAYBE inputs there are, and store their indexes in
	 * maybeEntries. If there are too many MAYBE inputs, it's not feasible to
	 * test all combinations, so give up and return MAYBE.
	 */
	nmaybe = 0;
	for (i = 0; i < key->nentries; i++)
	{
		if (key->entryRes[i] == GIN_MAYBE)
		{
			if (nmaybe >= MAX_MAYBE_ENTRIES)
				return GIN_MAYBE;
			maybeEntries[nmaybe++] = i;
		}
	}

	/*
	 * If none of the inputs were MAYBE, so we can just call consistent
	 * function as is.
	 */
	if (nmaybe == 0)
		return directBoolConsistentFn(key);

	/* First call consistent function with all the maybe-inputs set FALSE */
	for (i = 0; i < nmaybe; i++)
		key->entryRes[maybeEntries[i]] = GIN_FALSE;
	curResult = directBoolConsistentFn(key);

	for (;;)
	{
		/* Twiddle the entries for next combination. */
		for (i = 0; i < nmaybe; i++)
		{
			if (key->entryRes[maybeEntries[i]] == GIN_FALSE)
			{
				key->entryRes[maybeEntries[i]] = GIN_TRUE;
				break;
			}
			else
				key->entryRes[maybeEntries[i]] = GIN_FALSE;
		}
		if (i == nmaybe)
			break;

		boolResult = directBoolConsistentFn(key);
		recheck |= key->recheckCurItem;

		if (curResult != boolResult)
			return GIN_MAYBE;
	}

	/* TRUE with recheck is taken to mean MAYBE */
	if (curResult == GIN_TRUE && recheck)
		curResult = GIN_MAYBE;

	return curResult;
}

/*
 * Set up the implementation of the consistent functions for a scan key.
 */
void
ginInitConsistentFunction(GinState *ginstate, GinScanKey key)
{
	if (key->searchMode == GIN_SEARCH_MODE_EVERYTHING)
	{
		key->boolConsistentFn = trueConsistentFn;
		key->triConsistentFn = trueTriConsistentFn;
	}
	else
	{
		key->consistentFmgrInfo = &ginstate->consistentFn[key->attnum - 1];
		key->triConsistentFmgrInfo = &ginstate->triConsistentFn[key->attnum - 1];
		key->collation = ginstate->supportCollation[key->attnum - 1];

		if (OidIsValid(ginstate->consistentFn[key->attnum - 1].fn_oid))
			key->boolConsistentFn = directBoolConsistentFn;
		else
			key->boolConsistentFn = shimBoolConsistentFn;

		if (OidIsValid(ginstate->triConsistentFn[key->attnum - 1].fn_oid))
			key->triConsistentFn = directTriConsistentFn;
		else
			key->triConsistentFn = shimTriConsistentFn;
	}
}
<commit_msg>Simple fix for Postgres code to get it to compile on Ubuntu 16.04 / g++ 5.3.1 -- I dedicate this commit to the memory of @jarulraj<commit_after>/*-------------------------------------------------------------------------
 *
 * ginlogic.c
 *	  routines for performing binary- and ternary-logic consistent checks.
 *
 * A GIN operator___ class___ can provide a boolean or ternary consistent
 * function, or both.  This file provides both boolean and ternary
 * interfaces to the rest of the GIN code, even if only one of them is
 * implemented by the opclass.
 *
 * Providing a boolean interface when the opclass implements only the
 * ternary function is straightforward - just call the ternary function
 * with the check-array as is, and map the GIN_TRUE, GIN_FALSE, GIN_MAYBE
 * return codes to TRUE, FALSE and TRUE+recheck, respectively.  Providing
 * a ternary interface when the opclass only implements a boolean function
 * is implemented by calling the boolean function many times, with all the
 * MAYBE arguments set to all combinations of TRUE and FALSE (up to a
 * certain number of MAYBE arguments).
 *
 * (A boolean function is enough to determine if an item matches, but a
 * GIN scan can apply various optimizations if it can determine that an
 * item matches or doesn't match, even if it doesn't know if some of the
 * keys are present or not.  That's what the ternary consistent function
 * is used for.)
 *
 *
 * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *			src/backend/access/gin/ginlogic.c
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/gin_private.h"
#include "access/reloptions.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "storage/indexfsm.h"
#include "storage/lmgr.h"

/*
 * Maximum number of MAYBE inputs that shimTriConsistentFn will try to
 * resolve by calling all combinations.
 */
#define MAX_MAYBE_ENTRIES	4

/*
 * Dummy consistent functions for an EVERYTHING key.  Just claim it matches.
 */
static bool
trueConsistentFn(GinScanKey key)
{
	key->recheckCurItem = false;
	return true;
}
static GinTernaryValue
trueTriConsistentFn(GinScanKey key)
{
	return GIN_TRUE;
}

/*
 * A helper function for calling a regular, binary logic, consistent function.
 */
static bool
directBoolConsistentFn(GinScanKey key)
{
	/*
	 * Initialize recheckCurItem in case the consistentFn doesn't know it
	 * should set it.  The safe assumption in that case is to force recheck.
	 */
	key->recheckCurItem = true;

	return DatumGetBool(FunctionCall8Coll(key->consistentFmgrInfo,
										  key->collation,
										  PointerGetDatum(key->entryRes),
										  UInt16GetDatum(key->strategy),
										  key->query,
										  UInt32GetDatum(key->nuserentries),
										  PointerGetDatum(key->extra_data),
									   PointerGetDatum(&key->recheckCurItem),
										  PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
}

/*
 * A helper function for calling a native ternary logic consistent function.
 */
static GinTernaryValue
directTriConsistentFn(GinScanKey key)
{
	return DatumGetGinTernaryValue(FunctionCall7Coll(
												  key->triConsistentFmgrInfo,
													 key->collation,
											  PointerGetDatum(key->entryRes),
											   UInt16GetDatum(key->strategy),
													 key->query,
										   UInt32GetDatum(key->nuserentries),
											PointerGetDatum(key->extra_data),
										   PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
}

/*
 * This function implements a binary logic consistency check, using a ternary
 * logic consistent function provided by the opclass. GIN_MAYBE return value
 * is interpreted as true with recheck flag.
 */
static bool
shimBoolConsistentFn(GinScanKey key)
{
	GinTernaryValue result;

	result = DatumGetGinTernaryValue(FunctionCall7Coll(
												  key->triConsistentFmgrInfo,
													   key->collation,
											  PointerGetDatum(key->entryRes),
											   UInt16GetDatum(key->strategy),
													   key->query,
										   UInt32GetDatum(key->nuserentries),
											PointerGetDatum(key->extra_data),
										   PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
	if (result == GIN_MAYBE)
	{
		key->recheckCurItem = true;
		return true;
	}
	else
	{
		key->recheckCurItem = false;
		return result;
	}
}

/*
 * This function implements a tri-state consistency check, using a boolean
 * consistent function provided by the opclass.
 *
 * Our strategy is to call consistentFn with MAYBE inputs replaced with every
 * combination of TRUE/FALSE. If consistentFn returns the same value for every
 * combination, that's the overall result. Otherwise, return MAYBE. Testing
 * every combination is O(n^2), so this is only feasible for a small number of
 * MAYBE inputs.
 *
 * NB: This function modifies the key->entryRes array!
 */
static GinTernaryValue
shimTriConsistentFn(GinScanKey key)
{
	int			nmaybe;
	int			maybeEntries[MAX_MAYBE_ENTRIES];
	int			i;
	bool		boolResult;
	bool		recheck = false;
	GinTernaryValue curResult;

	/*
	 * Count how many MAYBE inputs there are, and store their indexes in
	 * maybeEntries. If there are too many MAYBE inputs, it's not feasible to
	 * test all combinations, so give up and return MAYBE.
	 */
	nmaybe = 0;
	for (i = 0; i < key->nentries; i++)
	{
		if (static_cast<int>(key->entryRes[i]) == GIN_MAYBE)
		{
			if (nmaybe >= MAX_MAYBE_ENTRIES)
				return GIN_MAYBE;
			maybeEntries[nmaybe++] = i;
		}
	}

	/*
	 * If none of the inputs were MAYBE, so we can just call consistent
	 * function as is.
	 */
	if (nmaybe == 0)
		return directBoolConsistentFn(key);

	/* First call consistent function with all the maybe-inputs set FALSE */
	for (i = 0; i < nmaybe; i++)
		key->entryRes[maybeEntries[i]] = GIN_FALSE;
	curResult = directBoolConsistentFn(key);

	for (;;)
	{
		/* Twiddle the entries for next combination. */
		for (i = 0; i < nmaybe; i++)
		{
			if (key->entryRes[maybeEntries[i]] == GIN_FALSE)
			{
				key->entryRes[maybeEntries[i]] = GIN_TRUE;
				break;
			}
			else
				key->entryRes[maybeEntries[i]] = GIN_FALSE;
		}
		if (i == nmaybe)
			break;

		boolResult = directBoolConsistentFn(key);
		recheck |= key->recheckCurItem;

		if (curResult != boolResult)
			return GIN_MAYBE;
	}

	/* TRUE with recheck is taken to mean MAYBE */
	if (curResult == GIN_TRUE && recheck)
		curResult = GIN_MAYBE;

	return curResult;
}

/*
 * Set up the implementation of the consistent functions for a scan key.
 */
void
ginInitConsistentFunction(GinState *ginstate, GinScanKey key)
{
	if (key->searchMode == GIN_SEARCH_MODE_EVERYTHING)
	{
		key->boolConsistentFn = trueConsistentFn;
		key->triConsistentFn = trueTriConsistentFn;
	}
	else
	{
		key->consistentFmgrInfo = &ginstate->consistentFn[key->attnum - 1];
		key->triConsistentFmgrInfo = &ginstate->triConsistentFn[key->attnum - 1];
		key->collation = ginstate->supportCollation[key->attnum - 1];

		if (OidIsValid(ginstate->consistentFn[key->attnum - 1].fn_oid))
			key->boolConsistentFn = directBoolConsistentFn;
		else
			key->boolConsistentFn = shimBoolConsistentFn;

		if (OidIsValid(ginstate->triConsistentFn[key->attnum - 1].fn_oid))
			key->triConsistentFn = directTriConsistentFn;
		else
			key->triConsistentFn = shimTriConsistentFn;
	}
}
<|endoftext|>


<commit_before>/*=============================================================================

  Library: XNAT/Core

  Copyright (c) University College London,
    Centre for Medical Image Computing

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=============================================================================*/

#include "ctkXnatResource.h"

#include "ctkXnatSession.h"
#include "ctkXnatObjectPrivate.h"

//----------------------------------------------------------------------------
class ctkXnatResourcePrivate : public ctkXnatObjectPrivate
{
public:

  ctkXnatResourcePrivate()
  : ctkXnatObjectPrivate()
  {
  }

};

//----------------------------------------------------------------------------
ctkXnatResource::ctkXnatResource(ctkXnatObject* parent, const QString& schemaType)
: ctkXnatObject(*new ctkXnatResourcePrivate(), parent, schemaType)
{
}

//----------------------------------------------------------------------------
ctkXnatResource::~ctkXnatResource()
{
}

//----------------------------------------------------------------------------
QString ctkXnatResource::resourceUri() const
{
  return QString("%1/resources/%2").arg(parent()->resourceUri(), this->property("xnat_abstractresource_id"));
}

//----------------------------------------------------------------------------
void ctkXnatResource::reset()
{
  ctkXnatObject::reset();
}

//----------------------------------------------------------------------------
void ctkXnatResource::fetchImpl()
{
  QString resourceFilesUri = this->resourceUri() + "/files";
  ctkXnatSession* const session = this->session();
  QUuid queryId = session->httpGet(resourceFilesUri);

  QList<ctkXnatObject*> files = session->httpResults(queryId,
                                                     ctkXnatDefaultSchemaTypes::XSI_FILE);

  foreach (ctkXnatObject* file, files)
  {
    QString label = file->property("Name");
    if (label.isEmpty())
    {
      label = "NO NAME";
    }
    file->setProperty("label", label);
    this->add(file);
  }
}

//----------------------------------------------------------------------------
void ctkXnatResource::download(const QString& /*filename*/)
{
//  this->session()->download(this, filename);
}
<commit_msg>ctkXnatResource download function implemented<commit_after>/*=============================================================================

  Library: XNAT/Core

  Copyright (c) University College London,
    Centre for Medical Image Computing

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=============================================================================*/

#include "ctkXnatResource.h"

#include "ctkXnatSession.h"
#include "ctkXnatObjectPrivate.h"

//----------------------------------------------------------------------------
class ctkXnatResourcePrivate : public ctkXnatObjectPrivate
{
public:

  ctkXnatResourcePrivate()
  : ctkXnatObjectPrivate()
  {
  }

};

//----------------------------------------------------------------------------
ctkXnatResource::ctkXnatResource(ctkXnatObject* parent, const QString& schemaType)
: ctkXnatObject(*new ctkXnatResourcePrivate(), parent, schemaType)
{
}

//----------------------------------------------------------------------------
ctkXnatResource::~ctkXnatResource()
{
}

//----------------------------------------------------------------------------
QString ctkXnatResource::resourceUri() const
{
  return QString("%1/resources/%2").arg(parent()->resourceUri(), this->property("xnat_abstractresource_id"));
}

//----------------------------------------------------------------------------
void ctkXnatResource::reset()
{
  ctkXnatObject::reset();
}

//----------------------------------------------------------------------------
void ctkXnatResource::fetchImpl()
{
  QString resourceFilesUri = this->resourceUri() + "/files";
  ctkXnatSession* const session = this->session();
  QUuid queryId = session->httpGet(resourceFilesUri);

  QList<ctkXnatObject*> files = session->httpResults(queryId,
                                                     ctkXnatDefaultSchemaTypes::XSI_FILE);

  foreach (ctkXnatObject* file, files)
  {
    QString label = file->property("Name");
    if (label.isEmpty())
    {
      label = "NO NAME";
    }
    file->setProperty("label", label);
    this->add(file);
  }
}

//----------------------------------------------------------------------------
void ctkXnatResource::download(const QString& filename)
{
  this->session()->download(this, filename);
}
<|endoftext|>


<commit_before>#include <ncurses.h>
#include <sstream>
#include <algorithm>

#include "display/Window.h"

Window::Window(uint32_t width, uint32_t height)
{
	_level = NULL;
	_super_win = NULL;

	createWindow(width, height, 0, 0);
}

Window::Window(uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	_level = NULL;
	_super_win = NULL;

	createWindow(width, height, x, y);
}

Window::Window(Level* level)
{
	_level = level;
	_super_win = NULL;

	createWindow(level->getWidth(), level->getHeight(), 0, 0);

	for(uint32_t x = 0; x < _level->getWidth(); x++)
	{
		for(uint32_t y = 0; y < _level->getHeight(); y++)
		{
			add(x, y, _level->getTile(x, y).getDisplay());
		}
	}
}

Window::Window(Window* super_win, uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	_level = NULL;
	_super_win = super_win;

	createWindow(width, height, x, y);
}

uint32_t Window::getWidth()
{
	if(NULL == _super_win)
	{
		return _width;
	} else {
		return _super_win->getWidth();
	}
}

uint32_t Window::getHeight()
{
	if(NULL == _super_win)
	{
		return _height;
	} else {
		return _super_win->getHeight();
	}
}

uint32_t Window::getX()
{
	if(NULL == _super_win)
	{
		return _x;
	} else {
		return _super_win->getX();
	}
}

uint32_t Window::getY()
{
	if(NULL == _super_win)
	{
		return _y;
	} else {
		return _super_win->getY();
	}
}

uint32_t Window::getViewWidth()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _width;
	}
}

uint32_t Window::getViewHeight()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _height;
	}
}

uint32_t Window::getViewX()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _view_x;
	}
}

uint32_t Window::getViewY()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _view_y;
	}
}

void Window::addBorder()
{
	//Default border, using the 3-char method for ease of maintenance
	addBorder('|', '-', '+');
}

void Window::addBorder(char sides, char topbot, char corners)
{
	//Apply border to all sides and corners
	addBorder(sides, sides, topbot, topbot, corners, corners, corners, corners);
}

void Window::addBorder(char left, char right, char top, char bottom, char topleft, char topright, char botleft, char botright)
{
	//Apply the specified border to the window
	wborder(_win, left, right, top, bottom, topleft, topright, botleft, botright);
}

void Window::refresh()
{
	wrefresh(_win);
}

void Window::add(uint32_t x, uint32_t y, char c)
{
	if(x < _width && y < _height)
	{
		mvwaddch(_win, y, x, c);
	}
}

void Window::add(uint32_t x, uint32_t y, std::string str)
{
	if(x < _width && y < _height)
	{
		mvwprintw(_win, y, x, str.c_str());
	}
}

void Window::addInt(uint32_t x, uint32_t y, int num)
{
	//String stream conversion; seems rather hacky, but without mandating C++11
	//support (which is not yet widely supported) it's the best we got...
	//Performance improvements (using a static stream) based on the answer and
	//code found here: http://bit.ly/1cfvyMW
	static std::stringstream ss;
	ss.seekp(0l);
	ss.str("");
	ss << num;
	//No reason to duplicate code now that we have the string
	add(x, y, ss.str());
}

void Window::erase(uint32_t x, uint32_t y)
{
	if(x < _width && y < _height)
	{
		/// @todo Is there a "proper" erase?
		add(y, x, ' ');
	}
}

void Window::moveTo(uint32_t x, uint32_t y)
{
	//Make sure our sub-window won't leave our window's boundaries.
	x = std::min(x, getWidth() - getViewWidth());
	y = std::min(y, getHeight() - getViewHeight());

	//Store this position for later
	_view_x = x;
	_view_y = y;

	//Move the sub-window relative to the window.
	mvderwin(_win, y, x);
}

void Window::moveBy(int32_t dx, int32_t dy)
{
	int32_t x = std::max(0, (int32_t)getViewX()+dx);
	int32_t y = std::max(0, (int32_t)getViewY()+dy);

	if(dx < 0 && abs(dx) > (int32_t)x)
	{
		x = 0;
	} else {
		x += dx;
	}

	if(dy < 0 && abs(dy) > (int32_t)y)
	{
		y = 0;
	} else {
		y += dy;
	}

	moveTo(x, y);
}

void Window::center()
{
	//Move the sub-window
	center(getWidth()/2, getHeight()/2);
}

void Window::center(uint32_t x, uint32_t y)
{
	//Calculate where our sub-window's x,y should be when centered on this x,y
	uint32_t centered_x = x - getViewWidth()/2;
	uint32_t centered_y = y - getViewHeight()/2;

	//Move the sub-window
	moveTo(centered_x, centered_y);
}

void Window::createWindow(uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	//Stash width and height for later reference.
	_width = width;
	_height = height;

	//Set x and y to 0.
	_x = x;
	_y = y;

	//Default sub-window position to 0,0
	_view_x = 0;
	_view_y = 0;

	if(NULL == _super_win)
	{
		//Create the window and store its pointer.
		_win = newwin(_height, _width, _y, _x);
	} else {
		//Create a subwindow
		_win = subwin(_super_win->_win, _height, _width, _y, _x);
	}
}

<commit_msg>Bugfix: moveBy method no longer doubles dx/dy.<commit_after>#include <ncurses.h>
#include <sstream>
#include <algorithm>

#include "display/Window.h"

Window::Window(uint32_t width, uint32_t height)
{
	_level = NULL;
	_super_win = NULL;

	createWindow(width, height, 0, 0);
}

Window::Window(uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	_level = NULL;
	_super_win = NULL;

	createWindow(width, height, x, y);
}

Window::Window(Level* level)
{
	_level = level;
	_super_win = NULL;

	createWindow(level->getWidth(), level->getHeight(), 0, 0);

	for(uint32_t x = 0; x < _level->getWidth(); x++)
	{
		for(uint32_t y = 0; y < _level->getHeight(); y++)
		{
			add(x, y, _level->getTile(x, y).getDisplay());
		}
	}
}

Window::Window(Window* super_win, uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	_level = NULL;
	_super_win = super_win;

	createWindow(width, height, x, y);
}

uint32_t Window::getWidth()
{
	if(NULL == _super_win)
	{
		return _width;
	} else {
		return _super_win->getWidth();
	}
}

uint32_t Window::getHeight()
{
	if(NULL == _super_win)
	{
		return _height;
	} else {
		return _super_win->getHeight();
	}
}

uint32_t Window::getX()
{
	if(NULL == _super_win)
	{
		return _x;
	} else {
		return _super_win->getX();
	}
}

uint32_t Window::getY()
{
	if(NULL == _super_win)
	{
		return _y;
	} else {
		return _super_win->getY();
	}
}

uint32_t Window::getViewWidth()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _width;
	}
}

uint32_t Window::getViewHeight()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _height;
	}
}

uint32_t Window::getViewX()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _view_x;
	}
}

uint32_t Window::getViewY()
{
	if(NULL == _super_win)
	{
		return 0;
	} else {
		return _view_y;
	}
}

void Window::addBorder()
{
	//Default border, using the 3-char method for ease of maintenance
	addBorder('|', '-', '+');
}

void Window::addBorder(char sides, char topbot, char corners)
{
	//Apply border to all sides and corners
	addBorder(sides, sides, topbot, topbot, corners, corners, corners, corners);
}

void Window::addBorder(char left, char right, char top, char bottom, char topleft, char topright, char botleft, char botright)
{
	//Apply the specified border to the window
	wborder(_win, left, right, top, bottom, topleft, topright, botleft, botright);
}

void Window::refresh()
{
	wrefresh(_win);
}

void Window::add(uint32_t x, uint32_t y, char c)
{
	if(x < _width && y < _height)
	{
		mvwaddch(_win, y, x, c);
	}
}

void Window::add(uint32_t x, uint32_t y, std::string str)
{
	if(x < _width && y < _height)
	{
		mvwprintw(_win, y, x, str.c_str());
	}
}

void Window::addInt(uint32_t x, uint32_t y, int num)
{
	//String stream conversion; seems rather hacky, but without mandating C++11
	//support (which is not yet widely supported) it's the best we got...
	//Performance improvements (using a static stream) based on the answer and
	//code found here: http://bit.ly/1cfvyMW
	static std::stringstream ss;
	ss.seekp(0l);
	ss.str("");
	ss << num;
	//No reason to duplicate code now that we have the string
	add(x, y, ss.str());
}

void Window::erase(uint32_t x, uint32_t y)
{
	if(x < _width && y < _height)
	{
		/// @todo Is there a "proper" erase?
		add(y, x, ' ');
	}
}

void Window::moveTo(uint32_t x, uint32_t y)
{
	//Make sure our sub-window won't leave our window's boundaries.
	x = std::min(x, getWidth() - getViewWidth());
	y = std::min(y, getHeight() - getViewHeight());

	//Store this position for later
	_view_x = x;
	_view_y = y;

	//Move the sub-window relative to the window.
	mvderwin(_win, y, x);
}

void Window::moveBy(int32_t dx, int32_t dy)
{
	int32_t x = std::max(0, (int32_t)getViewX()+dx);
	int32_t y = std::max(0, (int32_t)getViewY()+dy);

	moveTo(x, y);
}

void Window::center()
{
	//Move the sub-window
	center(getWidth()/2, getHeight()/2);
}

void Window::center(uint32_t x, uint32_t y)
{
	//Calculate where our sub-window's x,y should be when centered on this x,y
	uint32_t centered_x = x - getViewWidth()/2;
	uint32_t centered_y = y - getViewHeight()/2;

	//Move the sub-window
	moveTo(centered_x, centered_y);
}

void Window::createWindow(uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	//Stash width and height for later reference.
	_width = width;
	_height = height;

	//Set x and y to 0.
	_x = x;
	_y = y;

	//Default sub-window position to 0,0
	_view_x = 0;
	_view_y = 0;

	if(NULL == _super_win)
	{
		//Create the window and store its pointer.
		_win = newwin(_height, _width, _y, _x);
	} else {
		//Create a subwindow
		_win = subwin(_super_win->_win, _height, _width, _y, _x);
	}
}

<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

bool socketError = false;

int DDV_Listen(int port){
  int s = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);//port 8888
  inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);//listen on all interfaces
  int ret = bind(s, (sockaddr*)&addr, sizeof(addr));//bind to all interfaces, chosen port
  if (ret == 0){
    ret = listen(s, 100);//start listening, backlog of 100 allowed
    if (ret == 0){
      return s;
    }else{
      printf("Listen failed! Error: %s\n", strerror(errno));
      close(s);
      return 0;
    }
  }else{
    printf("Binding failed! Error: %s\n", strerror(errno));
    close(s);
    return 0;
  }
}

int DDV_Accept(int sock){
  return accept(sock, 0, 0);
}

bool DDV_write(void * buffer, int width, int count, int sock){
  int sofar = 0;
  int todo = width*count;
  while (sofar != todo){
    int r = send(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r < 0){
      socketError = true;
      printf("Could not write! %s\n", strerror(errno));
      return false;
    }
    sofar += r;
  }
  return true;
}

bool DDV_read(void * buffer, int width, int count, int sock){
  int sofar = 0;
  int todo = width*count;
  while (sofar != todo){
    int r = recv(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r < 0){
      socketError = true;
      printf("Could not read! %s\n", strerror(errno));
      return false;
    }
    sofar += r;
  }
  return true;
}
<commit_msg>Fix voor afsluiten verbinding...<commit_after>#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

bool socketError = false;

int DDV_Listen(int port){
  int s = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);//port 8888
  inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);//listen on all interfaces
  int ret = bind(s, (sockaddr*)&addr, sizeof(addr));//bind to all interfaces, chosen port
  if (ret == 0){
    ret = listen(s, 100);//start listening, backlog of 100 allowed
    if (ret == 0){
      return s;
    }else{
      printf("Listen failed! Error: %s\n", strerror(errno));
      close(s);
      return 0;
    }
  }else{
    printf("Binding failed! Error: %s\n", strerror(errno));
    close(s);
    return 0;
  }
}

int DDV_Accept(int sock){
  return accept(sock, 0, 0);
}

bool DDV_write(void * buffer, int width, int count, int sock){
  int sofar = 0;
  int todo = width*count;
  while (sofar != todo){
    int r = send(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r <= 0){
      socketError = true;
      printf("Could not write! %s\n", strerror(errno));
      return false;
    }
    sofar += r;
  }
  return true;
}

bool DDV_read(void * buffer, int width, int count, int sock){
  int sofar = 0;
  int todo = width*count;
  while (sofar != todo){
    int r = recv(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r <= 0){
      socketError = true;
      printf("Could not read! %s\n", strerror(errno));
      return false;
    }
    sofar += r;
  }
  return true;
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/CXX11/Tensor>

using Eigen::Tensor;
using Eigen::RowMajor;

static void test_simple_lvalue_ref()
{
  Tensor<int, 1> input(6);
  input.setRandom();

  TensorRef<Tensor<int, 1>> ref3(input);
  TensorRef<Tensor<int, 1>> ref4 = input;

  VERIFY_IS_EQUAL(ref3.data(), input.data());
  VERIFY_IS_EQUAL(ref4.data(), input.data());

  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(ref3(i), input(i));
    VERIFY_IS_EQUAL(ref4(i), input(i));
  }

  for (int i = 0; i < 6; ++i) {
    ref3.coeffRef(i) = i;
  }
  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(input(i), i);
  }
  for (int i = 0; i < 6; ++i) {
    ref4.coeffRef(i) = -i * 2;
  }
  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(input(i), -i*2);
  }
}

static void test_simple_rvalue_ref()
{
  Tensor<int, 1> input1(6);
  input1.setRandom();
  Tensor<int, 1> input2(6);
  input2.setRandom();

  TensorRef<Tensor<int, 1>> ref3(input1 + input2);
  TensorRef<Tensor<int, 1>> ref4 = input1 + input2;

  VERIFY_IS_NOT_EQUAL(ref3.data(), input1.data());
  VERIFY_IS_NOT_EQUAL(ref4.data(), input1.data());
  VERIFY_IS_NOT_EQUAL(ref3.data(), input2.data());
  VERIFY_IS_NOT_EQUAL(ref4.data(), input2.data());

  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(ref3(i), input1(i) + input2(i));
    VERIFY_IS_EQUAL(ref4(i), input1(i) + input2(i));
  }
}

static void test_multiple_dims()
{
  Tensor<float, 3> input(3,5,7);
  input.setRandom();

  TensorRef<Tensor<float, 3>> ref(input);
  VERIFY_IS_EQUAL(ref.data(), input.data());
  VERIFY_IS_EQUAL(ref.dimension(0), 3);
  VERIFY_IS_EQUAL(ref.dimension(1), 5);
  VERIFY_IS_EQUAL(ref.dimension(2), 7);

  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(ref(i,j,k), input(i,j,k));
      }
    }
  }
}

static void test_slice()
{
  Tensor<float, 5> tensor(2,3,5,7,11);
  tensor.setRandom();

  Eigen::DSizes<ptrdiff_t, 5> indices(1,2,3,4,5);
  Eigen::DSizes<ptrdiff_t, 5> sizes(1,1,1,1,1);
  TensorRef<Tensor<float, 5>> slice = tensor.slice(indices, sizes);
  VERIFY_IS_EQUAL(slice(0,0,0,0,0), tensor(1,2,3,4,5));

  Eigen::DSizes<ptrdiff_t, 5> indices2(1,1,3,4,5);
  Eigen::DSizes<ptrdiff_t, 5> sizes2(1,1,2,2,3);
  slice = tensor.slice(indices2, sizes2);
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) {
      for (int k = 0; k < 3; ++k) {
        VERIFY_IS_EQUAL(slice(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
      }
    }
  }

  Eigen::DSizes<ptrdiff_t, 5> indices3(0,0,0,0,0);
  Eigen::DSizes<ptrdiff_t, 5> sizes3(2,3,1,1,1);
  slice = tensor.slice(indices3, sizes3);
  VERIFY_IS_EQUAL(slice.data(), tensor.data());
}

static void test_ref_of_ref()
{
  Tensor<float, 3> input(3,5,7);
  input.setRandom();

  TensorRef<Tensor<float, 3>> ref(input);
  TensorRef<Tensor<float, 3>> ref_of_ref(ref);
  TensorRef<Tensor<float, 3>> ref_of_ref2;
  ref_of_ref2 = ref;

  VERIFY_IS_EQUAL(ref_of_ref.data(), input.data());
  VERIFY_IS_EQUAL(ref_of_ref.dimension(0), 3);
  VERIFY_IS_EQUAL(ref_of_ref.dimension(1), 5);
  VERIFY_IS_EQUAL(ref_of_ref.dimension(2), 7);

  VERIFY_IS_EQUAL(ref_of_ref2.data(), input.data());
  VERIFY_IS_EQUAL(ref_of_ref2.dimension(0), 3);
  VERIFY_IS_EQUAL(ref_of_ref2.dimension(1), 5);
  VERIFY_IS_EQUAL(ref_of_ref2.dimension(2), 7);

  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(ref_of_ref(i,j,k), input(i,j,k));
        VERIFY_IS_EQUAL(ref_of_ref2(i,j,k), input(i,j,k));
     }
    }
  }
}

static void test_ref_in_expr()
{
  Tensor<float, 3> input(3,5,7);
  input.setRandom();
  TensorRef<Tensor<float, 3>> input_ref(input);

  Tensor<float, 3> result(3,5,7);
  result.setRandom();
  TensorRef<Tensor<float, 3>> result_ref(result);

  Tensor<float, 3> bias(3,5,7);
  bias.setRandom();

  result_ref = input_ref + bias;
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(result_ref(i,j,k), input(i,j,k) + bias(i,j,k));
        VERIFY_IS_NOT_EQUAL(result(i,j,k), input(i,j,k) + bias(i,j,k));
      }
    }
  }

  result = result_ref;
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(result(i,j,k), input(i,j,k) + bias(i,j,k));
      }
    }
  }
}

static void test_coeff_ref()
{
  Tensor<float, 5> tensor(2,3,5,7,11);
  tensor.setRandom();
  Tensor<float, 5> original = tensor;

  TensorRef<Tensor<float, 4>> slice = tensor.chip(7, 4);
  slice.coeffRef(0, 0, 0, 0) = 1.0f;
  slice.coeffRef(1, 0, 0, 0) += 2.0f;

  VERIFY_IS_EQUAL(tensor(0,0,0,0,7), 1.0f);
  VERIFY_IS_EQUAL(tensor(1,0,0,0,7), original(1,0,0,0,7) + 2.0f);
}

static void test_nested_ops_with_ref()
{
  Tensor<float, 4> t(2, 3, 5, 7);
  t.setRandom();
  TensorMap<Tensor<const float, 4> > m(t.data(), 2, 3, 5, 7);
  array<pair<ptrdiff_t, ptrdiff_t>, 4> paddings;
  paddings[0] = make_pair(0, 0);
  paddings[1] = make_pair(2, 1);
  paddings[2] = make_pair(3, 4);
  paddings[3] = make_pair(0, 0);
  Eigen::DSizes<Eigen::DenseIndex, 4> shuffle_dims{0, 1, 2, 3};
  TensorRef<Tensor<const float, 4> > ref(m.pad(paddings));
  array<pair<ptrdiff_t, ptrdiff_t>, 4> trivial;
  trivial[0] = make_pair(0, 0);
  trivial[1] = make_pair(0, 0);
  trivial[2] = make_pair(0, 0);
  trivial[3] = make_pair(0, 0);
  Tensor<float, 4> padded = ref.shuffle(shuffle_dims).pad(trivial);
  VERIFY_IS_EQUAL(padded.dimension(0), 2+0);
  VERIFY_IS_EQUAL(padded.dimension(1), 3+3);
  VERIFY_IS_EQUAL(padded.dimension(2), 5+7);
  VERIFY_IS_EQUAL(padded.dimension(3), 7+0);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 6; ++j) {
      for (int k = 0; k < 12; ++k) {
        for (int l = 0; l < 7; ++l) {
          if (j >= 2 && j < 5 && k >= 3 && k < 8) {
            VERIFY_IS_EQUAL(padded(i,j,k,l), t(i,j-2,k-3,l));
          } else {
            VERIFY_IS_EQUAL(padded(i,j,k,l), 0.0f);
          }
        }
      }
    }
  }
}

void test_cxx11_tensor_ref()
{
  CALL_SUBTEST(test_simple_lvalue_ref());
  CALL_SUBTEST(test_simple_rvalue_ref());
  CALL_SUBTEST(test_multiple_dims());
  CALL_SUBTEST(test_slice());
  CALL_SUBTEST(test_ref_of_ref());
  CALL_SUBTEST(test_ref_in_expr());
  CALL_SUBTEST(test_coeff_ref());
  CALL_SUBTEST(test_nested_ops_with_ref());
}
<commit_msg>Fixed compilation error with clang<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/CXX11/Tensor>

using Eigen::Tensor;
using Eigen::RowMajor;

static void test_simple_lvalue_ref()
{
  Tensor<int, 1> input(6);
  input.setRandom();

  TensorRef<Tensor<int, 1>> ref3(input);
  TensorRef<Tensor<int, 1>> ref4 = input;

  VERIFY_IS_EQUAL(ref3.data(), input.data());
  VERIFY_IS_EQUAL(ref4.data(), input.data());

  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(ref3(i), input(i));
    VERIFY_IS_EQUAL(ref4(i), input(i));
  }

  for (int i = 0; i < 6; ++i) {
    ref3.coeffRef(i) = i;
  }
  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(input(i), i);
  }
  for (int i = 0; i < 6; ++i) {
    ref4.coeffRef(i) = -i * 2;
  }
  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(input(i), -i*2);
  }
}

static void test_simple_rvalue_ref()
{
  Tensor<int, 1> input1(6);
  input1.setRandom();
  Tensor<int, 1> input2(6);
  input2.setRandom();

  TensorRef<Tensor<int, 1>> ref3(input1 + input2);
  TensorRef<Tensor<int, 1>> ref4 = input1 + input2;

  VERIFY_IS_NOT_EQUAL(ref3.data(), input1.data());
  VERIFY_IS_NOT_EQUAL(ref4.data(), input1.data());
  VERIFY_IS_NOT_EQUAL(ref3.data(), input2.data());
  VERIFY_IS_NOT_EQUAL(ref4.data(), input2.data());

  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_EQUAL(ref3(i), input1(i) + input2(i));
    VERIFY_IS_EQUAL(ref4(i), input1(i) + input2(i));
  }
}

static void test_multiple_dims()
{
  Tensor<float, 3> input(3,5,7);
  input.setRandom();

  TensorRef<Tensor<float, 3>> ref(input);
  VERIFY_IS_EQUAL(ref.data(), input.data());
  VERIFY_IS_EQUAL(ref.dimension(0), 3);
  VERIFY_IS_EQUAL(ref.dimension(1), 5);
  VERIFY_IS_EQUAL(ref.dimension(2), 7);

  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(ref(i,j,k), input(i,j,k));
      }
    }
  }
}

static void test_slice()
{
  Tensor<float, 5> tensor(2,3,5,7,11);
  tensor.setRandom();

  Eigen::DSizes<ptrdiff_t, 5> indices(1,2,3,4,5);
  Eigen::DSizes<ptrdiff_t, 5> sizes(1,1,1,1,1);
  TensorRef<Tensor<float, 5>> slice = tensor.slice(indices, sizes);
  VERIFY_IS_EQUAL(slice(0,0,0,0,0), tensor(1,2,3,4,5));

  Eigen::DSizes<ptrdiff_t, 5> indices2(1,1,3,4,5);
  Eigen::DSizes<ptrdiff_t, 5> sizes2(1,1,2,2,3);
  slice = tensor.slice(indices2, sizes2);
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) {
      for (int k = 0; k < 3; ++k) {
        VERIFY_IS_EQUAL(slice(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
      }
    }
  }

  Eigen::DSizes<ptrdiff_t, 5> indices3(0,0,0,0,0);
  Eigen::DSizes<ptrdiff_t, 5> sizes3(2,3,1,1,1);
  slice = tensor.slice(indices3, sizes3);
  VERIFY_IS_EQUAL(slice.data(), tensor.data());
}

static void test_ref_of_ref()
{
  Tensor<float, 3> input(3,5,7);
  input.setRandom();

  TensorRef<Tensor<float, 3>> ref(input);
  TensorRef<Tensor<float, 3>> ref_of_ref(ref);
  TensorRef<Tensor<float, 3>> ref_of_ref2;
  ref_of_ref2 = ref;

  VERIFY_IS_EQUAL(ref_of_ref.data(), input.data());
  VERIFY_IS_EQUAL(ref_of_ref.dimension(0), 3);
  VERIFY_IS_EQUAL(ref_of_ref.dimension(1), 5);
  VERIFY_IS_EQUAL(ref_of_ref.dimension(2), 7);

  VERIFY_IS_EQUAL(ref_of_ref2.data(), input.data());
  VERIFY_IS_EQUAL(ref_of_ref2.dimension(0), 3);
  VERIFY_IS_EQUAL(ref_of_ref2.dimension(1), 5);
  VERIFY_IS_EQUAL(ref_of_ref2.dimension(2), 7);

  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(ref_of_ref(i,j,k), input(i,j,k));
        VERIFY_IS_EQUAL(ref_of_ref2(i,j,k), input(i,j,k));
     }
    }
  }
}

static void test_ref_in_expr()
{
  Tensor<float, 3> input(3,5,7);
  input.setRandom();
  TensorRef<Tensor<float, 3>> input_ref(input);

  Tensor<float, 3> result(3,5,7);
  result.setRandom();
  TensorRef<Tensor<float, 3>> result_ref(result);

  Tensor<float, 3> bias(3,5,7);
  bias.setRandom();

  result_ref = input_ref + bias;
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(result_ref(i,j,k), input(i,j,k) + bias(i,j,k));
        VERIFY_IS_NOT_EQUAL(result(i,j,k), input(i,j,k) + bias(i,j,k));
      }
    }
  }

  result = result_ref;
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(result(i,j,k), input(i,j,k) + bias(i,j,k));
      }
    }
  }
}

static void test_coeff_ref()
{
  Tensor<float, 5> tensor(2,3,5,7,11);
  tensor.setRandom();
  Tensor<float, 5> original = tensor;

  TensorRef<Tensor<float, 4>> slice = tensor.chip(7, 4);
  slice.coeffRef(0, 0, 0, 0) = 1.0f;
  slice.coeffRef(1, 0, 0, 0) += 2.0f;

  VERIFY_IS_EQUAL(tensor(0,0,0,0,7), 1.0f);
  VERIFY_IS_EQUAL(tensor(1,0,0,0,7), original(1,0,0,0,7) + 2.0f);
}

static void test_nested_ops_with_ref()
{
  Tensor<float, 4> t(2, 3, 5, 7);
  t.setRandom();
  TensorMap<Tensor<const float, 4> > m(t.data(), 2, 3, 5, 7);
  array<std::pair<ptrdiff_t, ptrdiff_t>, 4> paddings;
  paddings[0] = std::make_pair(0, 0);
  paddings[1] = std::make_pair(2, 1);
  paddings[2] = std::make_pair(3, 4);
  paddings[3] = std::make_pair(0, 0);
  DSizes<Eigen::DenseIndex, 4> shuffle_dims{0, 1, 2, 3};
  TensorRef<Tensor<const float, 4> > ref(m.pad(paddings));
  array<std::pair<ptrdiff_t, ptrdiff_t>, 4> trivial;
  trivial[0] = std::make_pair(0, 0);
  trivial[1] = std::make_pair(0, 0);
  trivial[2] = std::make_pair(0, 0);
  trivial[3] = std::make_pair(0, 0);
  Tensor<float, 4> padded = ref.shuffle(shuffle_dims).pad(trivial);
  VERIFY_IS_EQUAL(padded.dimension(0), 2+0);
  VERIFY_IS_EQUAL(padded.dimension(1), 3+3);
  VERIFY_IS_EQUAL(padded.dimension(2), 5+7);
  VERIFY_IS_EQUAL(padded.dimension(3), 7+0);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 6; ++j) {
      for (int k = 0; k < 12; ++k) {
        for (int l = 0; l < 7; ++l) {
          if (j >= 2 && j < 5 && k >= 3 && k < 8) {
            VERIFY_IS_EQUAL(padded(i,j,k,l), t(i,j-2,k-3,l));
          } else {
            VERIFY_IS_EQUAL(padded(i,j,k,l), 0.0f);
          }
        }
      }
    }
  }
}

void test_cxx11_tensor_ref()
{
  CALL_SUBTEST(test_simple_lvalue_ref());
  CALL_SUBTEST(test_simple_rvalue_ref());
  CALL_SUBTEST(test_multiple_dims());
  CALL_SUBTEST(test_slice());
  CALL_SUBTEST(test_ref_of_ref());
  CALL_SUBTEST(test_ref_in_expr());
  CALL_SUBTEST(test_coeff_ref());
  CALL_SUBTEST(test_nested_ops_with_ref());
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <unsupported/Eigen/Polynomials>
#include <iostream>
#include <algorithm>

#ifdef HAS_GSL
#include "gsl_helper.h"
#endif

using namespace std;

namespace Eigen {
namespace internal {
template<int Size>
struct increment_if_fixed_size
{
  enum {
    ret = (Size == Dynamic) ? Dynamic : Size+1
  };
};
}
}

template<int Deg, typename POLYNOMIAL, typename SOLVER>
bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
{
  typedef typename POLYNOMIAL::Index Index;
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef typename SOLVER::RootsType    RootsType;
  typedef Matrix<Scalar,Deg,1>          EvalRootsType;

  const Index deg = pols.size()-1;

  psolve.compute( pols );
  const RootsType& roots( psolve.roots() );
  EvalRootsType evr( deg );
  for( int i=0; i<roots.size(); ++i ){
    evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }

  bool evalToZero = evr.isZero( test_precision<Scalar>() );
  if( !evalToZero )
  {
    cerr << "WRONG root: " << endl;
    cerr << "Polynomial: " << pols.transpose() << endl;
    cerr << "Roots found: " << roots.transpose() << endl;
    cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;
    cerr << endl;
  }

  #ifdef HAS_GSL
  if (internal::is_same_type< Scalar, double>::ret)
  {
    typedef GslTraits<Scalar> Gsl;
    RootsType gslRoots(deg);
    Gsl::eigen_poly_solve( pols, gslRoots );
    EvalRootsType gslEvr( deg );
    for( int i=0; i<gslRoots.size(); ++i )
    {
      gslEvr[i] = std::abs( poly_eval( pols, gslRoots[i] ) );
    }
    bool gslEvalToZero = gslEvr.isZero( test_precision<Scalar>() );
    if( !evalToZero )
    {
      if( !gslEvalToZero ){
        cerr << "GSL also failed" << endl; }
      else{
        cerr << "GSL did NOT failed" << endl; }
      cerr << "GSL roots found: " << gslRoots.transpose() << endl;
      cerr << "Abs value of the polynomial at the GSL roots: " << gslEvr.transpose() << endl;
      cerr << endl;
    }
  }
  #endif //< HAS_GSL

  std::vector<Scalar> rootModuli( roots.size() );
  Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
  aux = roots.array().abs();
  std::sort( rootModuli.begin(), rootModuli.end() );
  bool distinctModuli=true;
  for( size_t i=1; i<rootModuli.size() && distinctModuli; ++i )
  {
    if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){
      distinctModuli = false; }
  }
  VERIFY( evalToZero || !distinctModuli );

  return distinctModuli;
}

template<int Deg, typename POLYNOMIAL>
void evalSolver( const POLYNOMIAL& pols )
{
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
}

template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
{
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
  {
    //It is supposed that
    // 1) the roots found are correct
    // 2) the roots have distinct moduli

    typedef typename POLYNOMIAL::Scalar                 Scalar;
    typedef typename REAL_ROOTS::Scalar                 Real;

    typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;
    typedef typename PolynomialSolverType::RootsType    RootsType;
    typedef Matrix<Scalar,Deg,1>                        EvalRootsType;

    //Test realRoots
    std::vector< Real > calc_realRoots;
    psolve.realRoots( calc_realRoots );
    VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );

    const Scalar psPrec = internal::sqrt( test_precision<Scalar>() );

    for( size_t i=0; i<calc_realRoots.size(); ++i )
    {
      bool found = false;
      for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
      {
        if( internal::isApprox( calc_realRoots[i], real_roots[j] ), psPrec ){
          found = true; }
      }
      VERIFY( found );
    }

    //Test greatestRoot
    VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
          internal::abs( psolve.greatestRoot() ), psPrec ) );

    //Test smallestRoot
    VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
          internal::abs( psolve.smallestRoot() ), psPrec ) );

    bool hasRealRoot;
    //Test absGreatestRealRoot
    Real r = psolve.absGreatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), internal::abs(r), psPrec ) );  }

    //Test absSmallestRealRoot
    r = psolve.absSmallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), internal::abs( r ), psPrec ) ); }

    //Test greatestRealRoot
    r = psolve.greatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }

    //Test smallestRealRoot
    r = psolve.smallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
    VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }
  }
}

template<typename _Scalar, int _Deg>
void polynomialsolver(int deg)
{
  typedef internal::increment_if_fixed_size<_Deg>            Dim;
  typedef Matrix<_Scalar,Dim::ret,1>                  PolynomialType;
  typedef Matrix<_Scalar,_Deg,1>                      EvalRootsType;

  cout << "Standard cases" << endl;
  PolynomialType pols = PolynomialType::Random(deg+1);
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Hard cases" << endl;
  _Scalar multipleRoot = internal::random<_Scalar>();
  EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);
  roots_to_monicPolynomial( allRoots, pols );
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Test sugar" << endl;
  EvalRootsType realRoots = EvalRootsType::Random(deg);
  roots_to_monicPolynomial( realRoots, pols );
  evalSolverSugarFunction<_Deg>(
      pols,
      realRoots.template cast <
                    std::complex<
                         typename NumTraits<_Scalar>::Real
                         >
                    >(),
      realRoots );
}

template<typename _Scalar> void polynomialsolver_scalar()
{
  CALL_SUBTEST_1( (polynomialsolver<_Scalar,1>(1)) );
  CALL_SUBTEST_2( (polynomialsolver<_Scalar,2>(2)) );
  CALL_SUBTEST_3( (polynomialsolver<_Scalar,3>(3)) );
  CALL_SUBTEST_4( (polynomialsolver<_Scalar,4>(4)) );
  CALL_SUBTEST_5( (polynomialsolver<_Scalar,5>(5)) );
  CALL_SUBTEST_6( (polynomialsolver<_Scalar,6>(6)) );
  CALL_SUBTEST_7( (polynomialsolver<_Scalar,7>(7)) );
  CALL_SUBTEST_8( (polynomialsolver<_Scalar,8>(8)) );

  CALL_SUBTEST_9( (polynomialsolver<_Scalar,Dynamic>(
          internal::random<int>(9,45)
          )) );
}

void test_polynomialsolver()
{
  for(int i = 0; i < g_repeat; i++)
  {
    polynomialsolver_scalar<double>();
    polynomialsolver_scalar<float>();
  }
}
<commit_msg>make polynomialsolver test compile faster<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <unsupported/Eigen/Polynomials>
#include <iostream>
#include <algorithm>

#ifdef HAS_GSL
#include "gsl_helper.h"
#endif

using namespace std;

namespace Eigen {
namespace internal {
template<int Size>
struct increment_if_fixed_size
{
  enum {
    ret = (Size == Dynamic) ? Dynamic : Size+1
  };
};
}
}

template<int Deg, typename POLYNOMIAL, typename SOLVER>
bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
{
  typedef typename POLYNOMIAL::Index Index;
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef typename SOLVER::RootsType    RootsType;
  typedef Matrix<Scalar,Deg,1>          EvalRootsType;

  const Index deg = pols.size()-1;

  psolve.compute( pols );
  const RootsType& roots( psolve.roots() );
  EvalRootsType evr( deg );
  for( int i=0; i<roots.size(); ++i ){
    evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }

  bool evalToZero = evr.isZero( test_precision<Scalar>() );
  if( !evalToZero )
  {
    cerr << "WRONG root: " << endl;
    cerr << "Polynomial: " << pols.transpose() << endl;
    cerr << "Roots found: " << roots.transpose() << endl;
    cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;
    cerr << endl;
  }

  #ifdef HAS_GSL
  if (internal::is_same_type< Scalar, double>::ret)
  {
    typedef GslTraits<Scalar> Gsl;
    RootsType gslRoots(deg);
    Gsl::eigen_poly_solve( pols, gslRoots );
    EvalRootsType gslEvr( deg );
    for( int i=0; i<gslRoots.size(); ++i )
    {
      gslEvr[i] = std::abs( poly_eval( pols, gslRoots[i] ) );
    }
    bool gslEvalToZero = gslEvr.isZero( test_precision<Scalar>() );
    if( !evalToZero )
    {
      if( !gslEvalToZero ){
        cerr << "GSL also failed" << endl; }
      else{
        cerr << "GSL did NOT failed" << endl; }
      cerr << "GSL roots found: " << gslRoots.transpose() << endl;
      cerr << "Abs value of the polynomial at the GSL roots: " << gslEvr.transpose() << endl;
      cerr << endl;
    }
  }
  #endif //< HAS_GSL

  std::vector<Scalar> rootModuli( roots.size() );
  Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
  aux = roots.array().abs();
  std::sort( rootModuli.begin(), rootModuli.end() );
  bool distinctModuli=true;
  for( size_t i=1; i<rootModuli.size() && distinctModuli; ++i )
  {
    if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){
      distinctModuli = false; }
  }
  VERIFY( evalToZero || !distinctModuli );

  return distinctModuli;
}

template<int Deg, typename POLYNOMIAL>
void evalSolver( const POLYNOMIAL& pols )
{
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
}

template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
{
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
  {
    //It is supposed that
    // 1) the roots found are correct
    // 2) the roots have distinct moduli

    typedef typename POLYNOMIAL::Scalar                 Scalar;
    typedef typename REAL_ROOTS::Scalar                 Real;

    typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;
    typedef typename PolynomialSolverType::RootsType    RootsType;
    typedef Matrix<Scalar,Deg,1>                        EvalRootsType;

    //Test realRoots
    std::vector< Real > calc_realRoots;
    psolve.realRoots( calc_realRoots );
    VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );

    const Scalar psPrec = internal::sqrt( test_precision<Scalar>() );

    for( size_t i=0; i<calc_realRoots.size(); ++i )
    {
      bool found = false;
      for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
      {
        if( internal::isApprox( calc_realRoots[i], real_roots[j] ), psPrec ){
          found = true; }
      }
      VERIFY( found );
    }

    //Test greatestRoot
    VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
          internal::abs( psolve.greatestRoot() ), psPrec ) );

    //Test smallestRoot
    VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
          internal::abs( psolve.smallestRoot() ), psPrec ) );

    bool hasRealRoot;
    //Test absGreatestRealRoot
    Real r = psolve.absGreatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), internal::abs(r), psPrec ) );  }

    //Test absSmallestRealRoot
    r = psolve.absSmallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), internal::abs( r ), psPrec ) ); }

    //Test greatestRealRoot
    r = psolve.greatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }

    //Test smallestRealRoot
    r = psolve.smallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
    VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }
  }
}

template<typename _Scalar, int _Deg>
void polynomialsolver(int deg)
{
  typedef internal::increment_if_fixed_size<_Deg>            Dim;
  typedef Matrix<_Scalar,Dim::ret,1>                  PolynomialType;
  typedef Matrix<_Scalar,_Deg,1>                      EvalRootsType;

  cout << "Standard cases" << endl;
  PolynomialType pols = PolynomialType::Random(deg+1);
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Hard cases" << endl;
  _Scalar multipleRoot = internal::random<_Scalar>();
  EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);
  roots_to_monicPolynomial( allRoots, pols );
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Test sugar" << endl;
  EvalRootsType realRoots = EvalRootsType::Random(deg);
  roots_to_monicPolynomial( realRoots, pols );
  evalSolverSugarFunction<_Deg>(
      pols,
      realRoots.template cast <
                    std::complex<
                         typename NumTraits<_Scalar>::Real
                         >
                    >(),
      realRoots );
}

void test_polynomialsolver()
{
  for(int i = 0; i < g_repeat; i++)
  {
    CALL_SUBTEST_1( (polynomialsolver<float,1>(1)) );
    CALL_SUBTEST_2( (polynomialsolver<double,2>(2)) );
    CALL_SUBTEST_3( (polynomialsolver<double,3>(3)) );
    CALL_SUBTEST_4( (polynomialsolver<float,4>(4)) );
    CALL_SUBTEST_5( (polynomialsolver<double,5>(5)) );
    CALL_SUBTEST_6( (polynomialsolver<float,6>(6)) );
    CALL_SUBTEST_7( (polynomialsolver<float,7>(7)) );
    CALL_SUBTEST_8( (polynomialsolver<double,8>(8)) );

    CALL_SUBTEST_9( (polynomialsolver<float,Dynamic>(
            internal::random<int>(9,45)
            )) );
    CALL_SUBTEST_10((polynomialsolver<double,Dynamic>(
            internal::random<int>(9,45)
            )) );
  }
}
<|endoftext|>


<commit_before>// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#pragma once

#ifndef NAZARA_HASHDIGEST_HPP
#define NAZARA_HASHDIGEST_HPP

#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
#include <ostream>

class NAZARA_API NzHashDigest
{
	public:
		NzHashDigest();
		NzHashDigest(const NzString& hashName, const nzUInt8* digest, unsigned int length);
		NzHashDigest(const NzHashDigest& rhs);
		NzHashDigest(NzHashDigest&& rhs) noexcept;
		~NzHashDigest();

		bool IsValid() const;

		const nzUInt8* GetDigest() const;
		unsigned int GetDigestLength() const;
		NzString GetHashName() const;

		NzString ToHex() const;

		nzUInt8 operator[](unsigned int pos) const;

		NzHashDigest& operator=(const NzHashDigest& rhs);
		NzHashDigest& operator=(NzHashDigest&& rhs) noexcept;

		bool operator==(const NzHashDigest& rhs) const;
		bool operator!=(const NzHashDigest& rhs) const;
		bool operator<(const NzHashDigest& rhs) const;
		bool operator<=(const NzHashDigest& rhs) const;
		bool operator>(const NzHashDigest& rhs) const;
		bool operator>=(const NzHashDigest& rhs) const;

		NAZARA_API friend std::ostream& operator<<(std::ostream& out, const NzHashDigest& string);

	private:
		NzString m_hashName;
		nzUInt8* m_digest;
		unsigned int m_digestLength;
};

#endif // NAZARA_HASHDIGEST_HPP
<commit_msg>Added TODO<commit_after>// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#pragma once

#ifndef NAZARA_HASHDIGEST_HPP
#define NAZARA_HASHDIGEST_HPP

///TODO: Remplacer par ByteArray

#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
#include <ostream>

class NAZARA_API NzHashDigest
{
	public:
		NzHashDigest();
		NzHashDigest(const NzString& hashName, const nzUInt8* digest, unsigned int length);
		NzHashDigest(const NzHashDigest& rhs);
		NzHashDigest(NzHashDigest&& rhs) noexcept;
		~NzHashDigest();

		bool IsValid() const;

		const nzUInt8* GetDigest() const;
		unsigned int GetDigestLength() const;
		NzString GetHashName() const;

		NzString ToHex() const;

		nzUInt8 operator[](unsigned int pos) const;

		NzHashDigest& operator=(const NzHashDigest& rhs);
		NzHashDigest& operator=(NzHashDigest&& rhs) noexcept;

		bool operator==(const NzHashDigest& rhs) const;
		bool operator!=(const NzHashDigest& rhs) const;
		bool operator<(const NzHashDigest& rhs) const;
		bool operator<=(const NzHashDigest& rhs) const;
		bool operator>(const NzHashDigest& rhs) const;
		bool operator>=(const NzHashDigest& rhs) const;

		NAZARA_API friend std::ostream& operator<<(std::ostream& out, const NzHashDigest& string);

	private:
		NzString m_hashName;
		nzUInt8* m_digest;
		unsigned int m_digestLength;
};

#endif // NAZARA_HASHDIGEST_HPP
<|endoftext|>


<commit_before>/*
 * =====================================================================================
 *
 *       Filename:  ridge_main.cc
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  02/16/2009 10:55:21 AM EST
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Nikolaos Vasiloglou (NV), nvasil@ieee.org
 *        Company:
 *
 * =====================================================================================
 */
#include <string>
#include "fastlib/fastlib.h"
#include "ridge_regression.h"

int main(int argc, char *argv[]) {

  fx_module *module = fx_init(argc, argv, NULL);
  double lambda = fx_param_double(module, "lambda", 0.0);
  std::string predictors_file = fx_param_str_req(module, "predictors");
  std::string predictions_file = fx_param_str_req(module, "predictions");

  Matrix predictors;
  if (data::Load(predictors_file.c_str(), &predictors)==SUCCESS_FAIL) {
    FATAL("Unable to open file %s", predictors_file.c_str());
  }

  Matrix predictions;
  if (data::Load(predictions_file.c_str(), &predictions)==SUCCESS_FAIL) {
    FATAL("Unable to open file %s", predictions_file.c_str());
  }

  RidgeRegression engine;
  engine.Init(module, predictors, predictions);
  NOTIFY("Computing Regression...");

  if(fx_param_exists(module, "normal_equation_method")) {
    engine.Regress(lambda);
  }
  else {
    engine.SVDRegress(lambda);
  }
  NOTIFY("Regression Complete !");
  double square_error = engine.ComputeSquareError();
  NOTIFY("Squre Error:%g", square_error);
  fx_result_double(module, "square error", square_error);
  Matrix factors;
  engine.factors(&factors);
  std::string factors_file = fx_param_str(module, "factors", "factors.csv");
  NOTIFY("Saving factors...");
  data::Save(factors_file.c_str(), factors);
  fx_done(module);
  return 0;
}
<commit_msg>Minor cosmetic change to the driver.<commit_after>/*
 * =====================================================================================
 *
 *       Filename:  ridge_main.cc
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  02/16/2009 10:55:21 AM EST
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Nikolaos Vasiloglou (NV), nvasil@ieee.org
 *        Company:
 *
 * =====================================================================================
 */
#include <string>
#include "fastlib/fastlib.h"
#include "ridge_regression.h"

int main(int argc, char *argv[]) {

  fx_module *module = fx_init(argc, argv, NULL);
  double lambda = fx_param_double(module, "lambda", 0.0);
  std::string predictors_file = fx_param_str_req(module, "predictors");
  std::string predictions_file = fx_param_str_req(module, "predictions");

  Matrix predictors;
  if (data::Load(predictors_file.c_str(), &predictors)==SUCCESS_FAIL) {
    FATAL("Unable to open file %s", predictors_file.c_str());
  }

  Matrix predictions;
  if (data::Load(predictions_file.c_str(), &predictions)==SUCCESS_FAIL) {
    FATAL("Unable to open file %s", predictions_file.c_str());
  }

  RidgeRegression engine;
  engine.Init(module, predictors, predictions);
  NOTIFY("Computing Regression...");

  if(fx_param_exists(module, "normal_equation_method")) {
    engine.Regress(lambda);
  }
  else {
    engine.SVDRegress(lambda);
  }
  NOTIFY("Regression Complete !");
  double square_error = engine.ComputeSquareError();
  NOTIFY("Square Error:%g", square_error);
  fx_result_double(module, "square error", square_error);
  Matrix factors;
  engine.factors(&factors);
  std::string factors_file = fx_param_str(module, "factors", "factors.csv");
  NOTIFY("Saving factors...");
  data::Save(factors_file.c_str(), factors);
  fx_done(module);
  return 0;
}
<|endoftext|>