<commit_before>//
// Copyright (c) 2008-2016 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "../Precompiled.h"

#include "../IO/Log.h"
#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
#include "../Physics/PhysicsEvents.h"
#endif
#include "../Scene/LogicComponent.h"
#include "../Scene/Scene.h"
#include "../Scene/SceneEvents.h"

namespace Urho3D
{

LogicComponent::LogicComponent(Context* context) :
    Component(context),
    updateEventMask_(USE_UPDATE | USE_POSTUPDATE | USE_FIXEDUPDATE | USE_FIXEDPOSTUPDATE),
    currentEventMask_(0),
    delayedStartCalled_(false)
{
}

LogicComponent::~LogicComponent()
{
}

void LogicComponent::OnSetEnabled()
{
    UpdateEventSubscription();
}

void LogicComponent::Update(float timeStep)
{
}

void LogicComponent::PostUpdate(float timeStep)
{
}

void LogicComponent::FixedUpdate(float timeStep)
{
}

void LogicComponent::FixedPostUpdate(float timeStep)
{
}

void LogicComponent::SetUpdateEventMask(unsigned char mask)
{
    if (updateEventMask_ != mask)
    {
        updateEventMask_ = mask;
        UpdateEventSubscription();
    }
}

void LogicComponent::OnNodeSet(Node* node)
{
    if (node)
    {
        // Execute the user-defined start function
        Start();
    }
    else
    {
        // We are being detached from a node: execute user-defined stop function and prepare for destruction
        Stop();
    }
}

void LogicComponent::OnSceneSet(Scene* scene)
{
    if (scene)
        UpdateEventSubscription();
    else
    {
        UnsubscribeFromEvent(E_SCENEUPDATE);
        UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
        UnsubscribeFromEvent(E_PHYSICSPRESTEP);
        UnsubscribeFromEvent(E_PHYSICSPOSTSTEP);
#endif
        currentEventMask_ = 0;
    }
}

void LogicComponent::UpdateEventSubscription()
{
    Scene* scene = GetScene();
    if (!scene)
        return;

    bool enabled = IsEnabledEffective();

    bool needUpdate = enabled && ((updateEventMask_ & USE_UPDATE) || !delayedStartCalled_);
    if (needUpdate && !(currentEventMask_ & USE_UPDATE))
    {
        SubscribeToEvent(scene, E_SCENEUPDATE, URHO3D_HANDLER(LogicComponent, HandleSceneUpdate));
        currentEventMask_ |= USE_UPDATE;
    }
    else if (!needUpdate && (currentEventMask_ & USE_UPDATE))
    {
        UnsubscribeFromEvent(scene, E_SCENEUPDATE);
        currentEventMask_ &= ~USE_UPDATE;
    }

    bool needPostUpdate = enabled && (updateEventMask_ & USE_POSTUPDATE);
    if (needPostUpdate && !(currentEventMask_ & USE_POSTUPDATE))
    {
        SubscribeToEvent(scene, E_SCENEPOSTUPDATE, URHO3D_HANDLER(LogicComponent, HandleScenePostUpdate));
        currentEventMask_ |= USE_POSTUPDATE;
    }
    else if (!needUpdate && (currentEventMask_ & USE_POSTUPDATE))
    {
        UnsubscribeFromEvent(scene, E_SCENEPOSTUPDATE);
        currentEventMask_ &= ~USE_POSTUPDATE;
    }

#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
    Component* world = GetFixedUpdateSource();
    if (!world)
        return;

    bool needFixedUpdate = enabled && (updateEventMask_ & USE_FIXEDUPDATE);
    if (needFixedUpdate && !(currentEventMask_ & USE_FIXEDUPDATE))
    {
        SubscribeToEvent(world, E_PHYSICSPRESTEP, URHO3D_HANDLER(LogicComponent, HandlePhysicsPreStep));
        currentEventMask_ |= USE_FIXEDUPDATE;
    }
    else if (!needFixedUpdate && (currentEventMask_ & USE_FIXEDUPDATE))
    {
        UnsubscribeFromEvent(world, E_PHYSICSPRESTEP);
        currentEventMask_ &= ~USE_FIXEDUPDATE;
    }

    bool needFixedPostUpdate = enabled && (updateEventMask_ & USE_FIXEDPOSTUPDATE);
    if (needFixedPostUpdate && !(currentEventMask_ & USE_FIXEDPOSTUPDATE))
    {
        SubscribeToEvent(world, E_PHYSICSPOSTSTEP, URHO3D_HANDLER(LogicComponent, HandlePhysicsPostStep));
        currentEventMask_ |= USE_FIXEDPOSTUPDATE;
    }
    else if (!needFixedPostUpdate && (currentEventMask_ & USE_FIXEDPOSTUPDATE))
    {
        UnsubscribeFromEvent(world, E_PHYSICSPOSTSTEP);
        currentEventMask_ &= ~USE_FIXEDPOSTUPDATE;
    }
#endif
}

void LogicComponent::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace SceneUpdate;

    // Execute user-defined delayed start function before first update
    if (!delayedStartCalled_)
    {
        DelayedStart();
        delayedStartCalled_ = true;

        // If did not need actual update events, unsubscribe now
        if (!(updateEventMask_ & USE_UPDATE))
        {
            UnsubscribeFromEvent(GetScene(), E_SCENEUPDATE);
            currentEventMask_ &= ~USE_UPDATE;
            return;
        }
    }

    // Then execute user-defined update function
    Update(eventData[P_TIMESTEP].GetFloat());
}

void LogicComponent::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace ScenePostUpdate;

    // Execute user-defined post-update function
    PostUpdate(eventData[P_TIMESTEP].GetFloat());
}

#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)

void LogicComponent::HandlePhysicsPreStep(StringHash eventType, VariantMap& eventData)
{
    using namespace PhysicsPreStep;

    // Execute user-defined delayed start function before first fixed update if not called yet
    if (!delayedStartCalled_)
    {
        DelayedStart();
        delayedStartCalled_ = true;
    }

    // Execute user-defined fixed update function
    FixedUpdate(eventData[P_TIMESTEP].GetFloat());
}

void LogicComponent::HandlePhysicsPostStep(StringHash eventType, VariantMap& eventData)
{
    using namespace PhysicsPostStep;

    // Execute user-defined fixed post-update function
    FixedPostUpdate(eventData[P_TIMESTEP].GetFloat());
}

#endif

}
<commit_msg>Fix wrong bool check.<commit_after>//
// Copyright (c) 2008-2016 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "../Precompiled.h"

#include "../IO/Log.h"
#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
#include "../Physics/PhysicsEvents.h"
#endif
#include "../Scene/LogicComponent.h"
#include "../Scene/Scene.h"
#include "../Scene/SceneEvents.h"

namespace Urho3D
{

LogicComponent::LogicComponent(Context* context) :
    Component(context),
    updateEventMask_(USE_UPDATE | USE_POSTUPDATE | USE_FIXEDUPDATE | USE_FIXEDPOSTUPDATE),
    currentEventMask_(0),
    delayedStartCalled_(false)
{
}

LogicComponent::~LogicComponent()
{
}

void LogicComponent::OnSetEnabled()
{
    UpdateEventSubscription();
}

void LogicComponent::Update(float timeStep)
{
}

void LogicComponent::PostUpdate(float timeStep)
{
}

void LogicComponent::FixedUpdate(float timeStep)
{
}

void LogicComponent::FixedPostUpdate(float timeStep)
{
}

void LogicComponent::SetUpdateEventMask(unsigned char mask)
{
    if (updateEventMask_ != mask)
    {
        updateEventMask_ = mask;
        UpdateEventSubscription();
    }
}

void LogicComponent::OnNodeSet(Node* node)
{
    if (node)
    {
        // Execute the user-defined start function
        Start();
    }
    else
    {
        // We are being detached from a node: execute user-defined stop function and prepare for destruction
        Stop();
    }
}

void LogicComponent::OnSceneSet(Scene* scene)
{
    if (scene)
        UpdateEventSubscription();
    else
    {
        UnsubscribeFromEvent(E_SCENEUPDATE);
        UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
        UnsubscribeFromEvent(E_PHYSICSPRESTEP);
        UnsubscribeFromEvent(E_PHYSICSPOSTSTEP);
#endif
        currentEventMask_ = 0;
    }
}

void LogicComponent::UpdateEventSubscription()
{
    Scene* scene = GetScene();
    if (!scene)
        return;

    bool enabled = IsEnabledEffective();

    bool needUpdate = enabled && ((updateEventMask_ & USE_UPDATE) || !delayedStartCalled_);
    if (needUpdate && !(currentEventMask_ & USE_UPDATE))
    {
        SubscribeToEvent(scene, E_SCENEUPDATE, URHO3D_HANDLER(LogicComponent, HandleSceneUpdate));
        currentEventMask_ |= USE_UPDATE;
    }
    else if (!needUpdate && (currentEventMask_ & USE_UPDATE))
    {
        UnsubscribeFromEvent(scene, E_SCENEUPDATE);
        currentEventMask_ &= ~USE_UPDATE;
    }

    bool needPostUpdate = enabled && (updateEventMask_ & USE_POSTUPDATE);
    if (needPostUpdate && !(currentEventMask_ & USE_POSTUPDATE))
    {
        SubscribeToEvent(scene, E_SCENEPOSTUPDATE, URHO3D_HANDLER(LogicComponent, HandleScenePostUpdate));
        currentEventMask_ |= USE_POSTUPDATE;
    }
    else if (!needPostUpdate && (currentEventMask_ & USE_POSTUPDATE))
    {
        UnsubscribeFromEvent(scene, E_SCENEPOSTUPDATE);
        currentEventMask_ &= ~USE_POSTUPDATE;
    }

#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
    Component* world = GetFixedUpdateSource();
    if (!world)
        return;

    bool needFixedUpdate = enabled && (updateEventMask_ & USE_FIXEDUPDATE);
    if (needFixedUpdate && !(currentEventMask_ & USE_FIXEDUPDATE))
    {
        SubscribeToEvent(world, E_PHYSICSPRESTEP, URHO3D_HANDLER(LogicComponent, HandlePhysicsPreStep));
        currentEventMask_ |= USE_FIXEDUPDATE;
    }
    else if (!needFixedUpdate && (currentEventMask_ & USE_FIXEDUPDATE))
    {
        UnsubscribeFromEvent(world, E_PHYSICSPRESTEP);
        currentEventMask_ &= ~USE_FIXEDUPDATE;
    }

    bool needFixedPostUpdate = enabled && (updateEventMask_ & USE_FIXEDPOSTUPDATE);
    if (needFixedPostUpdate && !(currentEventMask_ & USE_FIXEDPOSTUPDATE))
    {
        SubscribeToEvent(world, E_PHYSICSPOSTSTEP, URHO3D_HANDLER(LogicComponent, HandlePhysicsPostStep));
        currentEventMask_ |= USE_FIXEDPOSTUPDATE;
    }
    else if (!needFixedPostUpdate && (currentEventMask_ & USE_FIXEDPOSTUPDATE))
    {
        UnsubscribeFromEvent(world, E_PHYSICSPOSTSTEP);
        currentEventMask_ &= ~USE_FIXEDPOSTUPDATE;
    }
#endif
}

void LogicComponent::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace SceneUpdate;

    // Execute user-defined delayed start function before first update
    if (!delayedStartCalled_)
    {
        DelayedStart();
        delayedStartCalled_ = true;

        // If did not need actual update events, unsubscribe now
        if (!(updateEventMask_ & USE_UPDATE))
        {
            UnsubscribeFromEvent(GetScene(), E_SCENEUPDATE);
            currentEventMask_ &= ~USE_UPDATE;
            return;
        }
    }

    // Then execute user-defined update function
    Update(eventData[P_TIMESTEP].GetFloat());
}

void LogicComponent::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace ScenePostUpdate;

    // Execute user-defined post-update function
    PostUpdate(eventData[P_TIMESTEP].GetFloat());
}

#if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)

void LogicComponent::HandlePhysicsPreStep(StringHash eventType, VariantMap& eventData)
{
    using namespace PhysicsPreStep;

    // Execute user-defined delayed start function before first fixed update if not called yet
    if (!delayedStartCalled_)
    {
        DelayedStart();
        delayedStartCalled_ = true;
    }

    // Execute user-defined fixed update function
    FixedUpdate(eventData[P_TIMESTEP].GetFloat());
}

void LogicComponent::HandlePhysicsPostStep(StringHash eventType, VariantMap& eventData)
{
    using namespace PhysicsPostStep;

    // Execute user-defined fixed post-update function
    FixedPostUpdate(eventData[P_TIMESTEP].GetFloat());
}

#endif

}
<|endoftext|>


<commit_before>/* Copyright (c) 2013-2015 Jeffrey Pfau
 *
 * 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 "InputProfile.h"

#include "InputController.h"

#include <QRegExp>

using namespace QGBA;

const InputProfile InputProfile::s_defaultMaps[] = {
	{
		"XInput Controller #\\d+", // XInput (Windows)
		(int[GBA_KEY_MAX]) {
		/*keyA      */ 11,
		/*keyB      */ 10,
		/*keySelect */  5,
		/*keyStart  */  4,
		/*keyRight  */  3,
		/*keyLeft   */  2,
		/*keyUp     */  0,
		/*keyDown   */  1,
		/*keyR      */  9,
		/*keyL      */  8
		},
		(ShortcutButton[]) {
			{"loadState", 12},
			{"saveState", 13},
			{}
		},
		(ShortcutAxis[]) {
			{"holdFastForward", GamepadAxisEvent::Direction::POSITIVE, 5},
			{"holdRewind", GamepadAxisEvent::Direction::POSITIVE, 4},
			{}
		}
	},
	{
		"Controller", // The Xbox 360 controller drivers on OS X are vague...
		(int[GBA_KEY_MAX]) {
		/*keyA      */  1,
		/*keyB      */  0,
		/*keySelect */  9,
		/*keyStart  */  8,
		/*keyRight  */ 14,
		/*keyLeft   */ 13,
		/*keyUp     */ 11,
		/*keyDown   */ 12,
		/*keyR      */  5,
		/*keyL      */  4
		},
		(ShortcutButton[]) {
			{"loadState", 2},
			{"saveState", 3},
			{}
		},
		(ShortcutAxis[]) {
			{"holdFastForward", GamepadAxisEvent::Direction::POSITIVE, 5},
			{"holdRewind", GamepadAxisEvent::Direction::POSITIVE, 2},
			{}
		}
	},
	{
		"PLAYSTATION\\(R\\)3 Controller", // DualShock 3 (OS X)
		(int[GBA_KEY_MAX]) {
		/*keyA      */ 13,
		/*keyB      */ 14,
		/*keySelect */  0,
		/*keyStart  */  3,
		/*keyRight  */  5,
		/*keyLeft   */  7,
		/*keyUp     */  4,
		/*keyDown   */  6,
		/*keyR      */ 11,
		/*keyL      */ 10
		},
		(ShortcutButton[]) {
			{"loadState", 15},
			{"saveState", 12},
			{"holdFastForward", 9},
			{"holdRewind", 8},
			{}
		}
	},
	{
		"Wiimote \\(..-..-..-..-..-..\\)", // WJoy (OS X)
		(int[GBA_KEY_MAX]) {
		/*keyA      */ 15,
		/*keyB      */ 16,
		/*keySelect */  7,
		/*keyStart  */  6,
		/*keyRight  */ 14,
		/*keyLeft   */ 13,
		/*keyUp     */ 11,
		/*keyDown   */ 12,
		/*keyR      */ 20,
		/*keyL      */ 19
		},
		(ShortcutButton[]) {
			{"loadState", 18},
			{"saveState", 17},
			{"holdFastForward", 22},
			{"holdRewind", 21},
			{}
		}
	},
};

constexpr InputProfile::InputProfile(const char* name,
                                     int keys[GBA_KEY_MAX],
                                     const ShortcutButton* shortcutButtons,
                                     const ShortcutAxis* shortcutAxes,
                                     AxisValue axes[GBA_KEY_MAX],
                                     const struct Coord& tiltAxis,
                                     const struct Coord& gyroAxis,
                                     float gyroSensitivity)
	: m_profileName(name)
	, m_keys {
		keys[GBA_KEY_A],
		keys[GBA_KEY_B],
		keys[GBA_KEY_SELECT],
		keys[GBA_KEY_START],
		keys[GBA_KEY_RIGHT],
		keys[GBA_KEY_LEFT],
		keys[GBA_KEY_UP],
		keys[GBA_KEY_DOWN],
		keys[GBA_KEY_R],
		keys[GBA_KEY_L]
	}
	, m_shortcutButtons(shortcutButtons)
	, m_shortcutAxes(shortcutAxes)
	, m_axes {
		axes[GBA_KEY_A],
		axes[GBA_KEY_B],
		axes[GBA_KEY_SELECT],
		axes[GBA_KEY_START],
		axes[GBA_KEY_RIGHT],
		axes[GBA_KEY_LEFT],
		axes[GBA_KEY_UP],
		axes[GBA_KEY_DOWN],
		axes[GBA_KEY_R],
		axes[GBA_KEY_L]
	}
	, m_tiltAxis(tiltAxis)
	, m_gyroAxis(gyroAxis)
	, m_gyroSensitivity(gyroSensitivity)
{
}

const InputProfile* InputProfile::findProfile(const QString& name) {
	for (size_t i = 0; i < sizeof(s_defaultMaps) / sizeof(*s_defaultMaps); ++i) {
		QRegExp re(s_defaultMaps[i].m_profileName);
		if (re.exactMatch(name)) {
			return &s_defaultMaps[i];
		}
	}
	return nullptr;
}

void InputProfile::apply(InputController* controller) const {
	for (size_t i = 0; i < GBA_KEY_MAX; ++i) {
#ifdef BUILD_SDL
		controller->bindKey(SDL_BINDING_BUTTON, m_keys[i], static_cast<GBAKey>(i));
		controller->bindAxis(SDL_BINDING_BUTTON, m_axes[i].axis, m_axes[i].direction, static_cast<GBAKey>(i));
#endif
	}
	controller->registerTiltAxisX(m_tiltAxis.x);
	controller->registerTiltAxisY(m_tiltAxis.y);
	controller->registerGyroAxisX(m_gyroAxis.x);
	controller->registerGyroAxisY(m_gyroAxis.y);
	controller->setGyroSensitivity(m_gyroSensitivity);
}

bool InputProfile::lookupShortcutButton(const QString& shortcutName, int* button) const {
	for (size_t i = 0; m_shortcutButtons[i].shortcut; ++i) {
		const ShortcutButton& shortcut = m_shortcutButtons[i];
		if (QLatin1String(shortcut.shortcut) == shortcutName) {
			*button = shortcut.button;
			return true;
		}
	}
	return false;
}

bool InputProfile::lookupShortcutAxis(const QString& shortcutName, int* axis, GamepadAxisEvent::Direction* direction) const {
	for (size_t i = 0; m_shortcutAxes[i].shortcut; ++i) {
		const ShortcutAxis& shortcut = m_shortcutAxes[i];
		if (QLatin1String(shortcut.shortcut) == shortcutName) {
			*axis = shortcut.axis;
			*direction = shortcut.direction;
			return true;
		}
	}
	return false;
}
<commit_msg>Qt: Add 360 profile for Linux<commit_after>/* Copyright (c) 2013-2015 Jeffrey Pfau
 *
 * 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 "InputProfile.h"

#include "InputController.h"

#include <QRegExp>

using namespace QGBA;

const InputProfile InputProfile::s_defaultMaps[] = {
	{
		"XInput Controller #\\d+", // XInput (Windows)
		(int[GBA_KEY_MAX]) {
		/*keyA      */ 11,
		/*keyB      */ 10,
		/*keySelect */  5,
		/*keyStart  */  4,
		/*keyRight  */  3,
		/*keyLeft   */  2,
		/*keyUp     */  0,
		/*keyDown   */  1,
		/*keyR      */  9,
		/*keyL      */  8
		},
		(ShortcutButton[]) {
			{"loadState", 12},
			{"saveState", 13},
			{}
		},
		(ShortcutAxis[]) {
			{"holdFastForward", GamepadAxisEvent::Direction::POSITIVE, 5},
			{"holdRewind", GamepadAxisEvent::Direction::POSITIVE, 4},
			{}
		}
	},
	{
		"(Microsoft X-Box 360 pad|Xbox Gamepad \\(userspace driver\\))", // Linux
		(int[GBA_KEY_MAX]) {
		/*keyA      */  1,
		/*keyB      */  0,
		/*keySelect */  6,
		/*keyStart  */  7,
		/*keyRight  */ -1,
		/*keyLeft   */ -1,
		/*keyUp     */ -1,
		/*keyDown   */ -1,
		/*keyR      */  5,
		/*keyL      */  4
		},
		(ShortcutButton[]) {
			{"loadState", 2},
			{"saveState", 3},
			{}
		},
		(ShortcutAxis[]) {
			{"holdFastForward", GamepadAxisEvent::Direction::POSITIVE, 5},
			{"holdRewind", GamepadAxisEvent::Direction::POSITIVE, 2},
			{}
		}
	},
	{
		"Controller", // The Xbox 360 controller drivers on OS X are vague...
		(int[GBA_KEY_MAX]) {
		/*keyA      */  1,
		/*keyB      */  0,
		/*keySelect */  9,
		/*keyStart  */  8,
		/*keyRight  */ 14,
		/*keyLeft   */ 13,
		/*keyUp     */ 11,
		/*keyDown   */ 12,
		/*keyR      */  5,
		/*keyL      */  4
		},
		(ShortcutButton[]) {
			{"loadState", 2},
			{"saveState", 3},
			{}
		},
		(ShortcutAxis[]) {
			{"holdFastForward", GamepadAxisEvent::Direction::POSITIVE, 5},
			{"holdRewind", GamepadAxisEvent::Direction::POSITIVE, 2},
			{}
		}
	},
	{
		"PLAYSTATION\\(R\\)3 Controller", // DualShock 3 (OS X)
		(int[GBA_KEY_MAX]) {
		/*keyA      */ 13,
		/*keyB      */ 14,
		/*keySelect */  0,
		/*keyStart  */  3,
		/*keyRight  */  5,
		/*keyLeft   */  7,
		/*keyUp     */  4,
		/*keyDown   */  6,
		/*keyR      */ 11,
		/*keyL      */ 10
		},
		(ShortcutButton[]) {
			{"loadState", 15},
			{"saveState", 12},
			{"holdFastForward", 9},
			{"holdRewind", 8},
			{}
		}
	},
	{
		"Wiimote \\(..-..-..-..-..-..\\)", // WJoy (OS X)
		(int[GBA_KEY_MAX]) {
		/*keyA      */ 15,
		/*keyB      */ 16,
		/*keySelect */  7,
		/*keyStart  */  6,
		/*keyRight  */ 14,
		/*keyLeft   */ 13,
		/*keyUp     */ 11,
		/*keyDown   */ 12,
		/*keyR      */ 20,
		/*keyL      */ 19
		},
		(ShortcutButton[]) {
			{"loadState", 18},
			{"saveState", 17},
			{"holdFastForward", 22},
			{"holdRewind", 21},
			{}
		}
	},
};

constexpr InputProfile::InputProfile(const char* name,
                                     int keys[GBA_KEY_MAX],
                                     const ShortcutButton* shortcutButtons,
                                     const ShortcutAxis* shortcutAxes,
                                     AxisValue axes[GBA_KEY_MAX],
                                     const struct Coord& tiltAxis,
                                     const struct Coord& gyroAxis,
                                     float gyroSensitivity)
	: m_profileName(name)
	, m_keys {
		keys[GBA_KEY_A],
		keys[GBA_KEY_B],
		keys[GBA_KEY_SELECT],
		keys[GBA_KEY_START],
		keys[GBA_KEY_RIGHT],
		keys[GBA_KEY_LEFT],
		keys[GBA_KEY_UP],
		keys[GBA_KEY_DOWN],
		keys[GBA_KEY_R],
		keys[GBA_KEY_L]
	}
	, m_shortcutButtons(shortcutButtons)
	, m_shortcutAxes(shortcutAxes)
	, m_axes {
		axes[GBA_KEY_A],
		axes[GBA_KEY_B],
		axes[GBA_KEY_SELECT],
		axes[GBA_KEY_START],
		axes[GBA_KEY_RIGHT],
		axes[GBA_KEY_LEFT],
		axes[GBA_KEY_UP],
		axes[GBA_KEY_DOWN],
		axes[GBA_KEY_R],
		axes[GBA_KEY_L]
	}
	, m_tiltAxis(tiltAxis)
	, m_gyroAxis(gyroAxis)
	, m_gyroSensitivity(gyroSensitivity)
{
}

const InputProfile* InputProfile::findProfile(const QString& name) {
	for (size_t i = 0; i < sizeof(s_defaultMaps) / sizeof(*s_defaultMaps); ++i) {
		QRegExp re(s_defaultMaps[i].m_profileName);
		if (re.exactMatch(name)) {
			return &s_defaultMaps[i];
		}
	}
	return nullptr;
}

void InputProfile::apply(InputController* controller) const {
	for (size_t i = 0; i < GBA_KEY_MAX; ++i) {
#ifdef BUILD_SDL
		controller->bindKey(SDL_BINDING_BUTTON, m_keys[i], static_cast<GBAKey>(i));
		controller->bindAxis(SDL_BINDING_BUTTON, m_axes[i].axis, m_axes[i].direction, static_cast<GBAKey>(i));
#endif
	}
	controller->registerTiltAxisX(m_tiltAxis.x);
	controller->registerTiltAxisY(m_tiltAxis.y);
	controller->registerGyroAxisX(m_gyroAxis.x);
	controller->registerGyroAxisY(m_gyroAxis.y);
	controller->setGyroSensitivity(m_gyroSensitivity);
}

bool InputProfile::lookupShortcutButton(const QString& shortcutName, int* button) const {
	for (size_t i = 0; m_shortcutButtons[i].shortcut; ++i) {
		const ShortcutButton& shortcut = m_shortcutButtons[i];
		if (QLatin1String(shortcut.shortcut) == shortcutName) {
			*button = shortcut.button;
			return true;
		}
	}
	return false;
}

bool InputProfile::lookupShortcutAxis(const QString& shortcutName, int* axis, GamepadAxisEvent::Direction* direction) const {
	for (size_t i = 0; m_shortcutAxes[i].shortcut; ++i) {
		const ShortcutAxis& shortcut = m_shortcutAxes[i];
		if (QLatin1String(shortcut.shortcut) == shortcutName) {
			*axis = shortcut.axis;
			*direction = shortcut.direction;
			return true;
		}
	}
	return false;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Opposite Renderer
 * For the full copyright and license information, please view the LICENSE.txt
 * file that was distributed with this source code.
*/

#include "StandaloneRenderManager.hxx"
#include "renderer/PPMOptixRenderer.h"
#include "renderer/PMOptixRenderer.h"
#include <QThread>
#include "renderer/Camera.h"
#include <QTime>
#include "scene/Scene.h"
#include "clientserver/RenderServerRenderRequest.h"
#include <QCoreApplication>
#include <QApplication>
#include "Application.hxx"

StandaloneRenderManager::StandaloneRenderManager(QApplication & qApplication, Application & application, const ComputeDevice& device) :
    m_device(device),
    m_renderer(new PMOptixRenderer()),
    m_nextIterationNumber(0),
    m_outputBuffer(NULL),
    m_currentScene(NULL),
    m_compileScene(false),
    m_application(application),
    m_noEmittedSignals(true),
	m_logger()
{
    connect(&application, SIGNAL(sequenceNumberIncremented()), this, SLOT(onSequenceNumberIncremented()));
    connect(&application, SIGNAL(runningStatusChanged()), this, SLOT(onRunningStatusChanged()));
    connect(&application.getSceneManager(), SIGNAL(sceneLoadingNew()), this, SLOT(onSceneLoadingNew()));
    connect(&application.getSceneManager(), SIGNAL(sceneUpdated()), this, SLOT(onSceneUpdated()));

    onSceneUpdated();

    connect(this, SIGNAL(continueRayTracing()),
            this, SLOT(onContinueRayTracing()),
            Qt::QueuedConnection);
}

SignalLogger& StandaloneRenderManager::logger()
{
	return m_logger;
}

StandaloneRenderManager::~StandaloneRenderManager()
{
    if(m_outputBuffer != NULL)
    {
        delete[] m_outputBuffer;
        m_outputBuffer = NULL;
    }
}

void StandaloneRenderManager::start()
{
    m_application.setRendererStatus(RendererStatus::INITIALIZING_ENGINE);
	m_renderer->initialize(m_device, &m_logger);
}

void StandaloneRenderManager::onContinueRayTracing()
{
    renderNextIteration();
    continueRayTracingIfRunningAsync();
}

void StandaloneRenderManager::renderNextIteration()
{
    try
    {
        if(m_application.getRunningStatus() == RunningStatus::RUNNING && m_currentScene != NULL)
        {
            m_noEmittedSignals = true;

            if(m_compileScene)
            {
                m_application.setRendererStatus(RendererStatus::INITIALIZING_SCENE);
                m_renderer->initScene(*m_currentScene);
                m_compileScene = false;
                m_application.setRendererStatus(RendererStatus::RENDERING);
            }

            // We only diplay one every X frames on screen (to make fair comparison with distributed renderer)
            bool shouldOutputIteration = m_nextIterationNumber % 1 == 0;

            const double PPMAlpha = 2.0/3.0;
            QVector<unsigned long long> iterationNumbers;
            QVector<double> ppmRadii;

            RenderServerRenderRequestDetails details (m_camera, QByteArray(m_currentScene->getSceneName()),
                m_application.getRenderMethod(), m_application.getWidth(), m_application.getHeight(), PPMAlpha);

            RenderServerRenderRequest renderRequest (m_application.getSequenceNumber(), iterationNumbers, ppmRadii, details);

            m_renderer->renderNextIteration(m_nextIterationNumber, m_nextIterationNumber, m_PPMRadius, shouldOutputIteration, renderRequest.getDetails());
            const double ppmRadiusSquared = m_PPMRadius*m_PPMRadius;
            const double ppmRadiusSquaredNew = ppmRadiusSquared*(m_nextIterationNumber+PPMAlpha)/double(m_nextIterationNumber+1);
            m_PPMRadius = sqrt(ppmRadiusSquaredNew);

            // Transfer the output buffer to CPU and signal ready for display

            if(shouldOutputIteration)
            {
                if(m_outputBuffer == NULL)
                {
                    m_outputBuffer = new float[2000*2000*3];
                }
                m_renderer->getOutputBuffer(m_outputBuffer);
                emit newFrameReadyForDisplay(m_outputBuffer, m_nextIterationNumber);
            }

            fillRenderStatistics();
            m_nextIterationNumber++;
			//m_application.setRunningStatus(RunningStatus::PAUSE);
        }
    }
    catch(const std::exception & E)
    {
        m_application.setRunningStatus(RunningStatus::PAUSE);
        QString error = QString("%1").arg(E.what());
        emit renderManagerError(error);
    }
}

/*
unsigned long long StandaloneRenderManager::getIterationNumber() const
{
    return m_nextIterationNumber-1;
}*/

void StandaloneRenderManager::fillRenderStatistics()
{
    m_application.getRenderStatisticsModel().setNumIterations(m_nextIterationNumber);
    m_application.getRenderStatisticsModel().setCurrentPPMRadius(m_PPMRadius);

    if(m_application.getRenderMethod() == RenderMethod::PROGRESSIVE_PHOTON_MAPPING)
    {
        m_application.getRenderStatisticsModel().setNumEmittedPhotonsPerIteration(PMOptixRenderer::EMITTED_PHOTONS_PER_ITERATION);
        m_application.getRenderStatisticsModel().setNumEmittedPhotons(PMOptixRenderer::EMITTED_PHOTONS_PER_ITERATION*m_nextIterationNumber);
    }
    else
    {
        m_application.getRenderStatisticsModel().setNumEmittedPhotonsPerIteration(0);
        m_application.getRenderStatisticsModel().setNumEmittedPhotons(0);

    }

}

// TODO this may be called very often for rapid camera changes.
void StandaloneRenderManager::onSequenceNumberIncremented()
{
    m_nextIterationNumber = 0;
    m_PPMRadius = m_application.getPPMSettingsModel().getPPMInitialRadius();
    m_camera = m_application.getCamera();
    continueRayTracingIfRunningAsync();
}

void StandaloneRenderManager::onSceneLoadingNew()
{
    //m_currentScene = NULL;
}

void StandaloneRenderManager::onSceneUpdated()
{
    IScene* scene = m_application.getSceneManager().getScene();
    if(scene != m_currentScene)
    {
        m_compileScene = true;
        m_currentScene = scene;
    }
}

void StandaloneRenderManager::wait()
{
    printf("StandaloneRenderManager::wait\n");
    /*m_thread->exit();
    m_thread->wait();*/
}

void StandaloneRenderManager::continueRayTracingIfRunningAsync()
{
    if(m_application.getRunningStatus() == RunningStatus::RUNNING && m_noEmittedSignals)
    {
        m_noEmittedSignals = false;
        emit continueRayTracing();
    }
}

void StandaloneRenderManager::onRunningStatusChanged()
{
    continueRayTracingIfRunningAsync();
}<commit_msg>Simplify RenderManager due to unused variables (e.g iterationNumber, PPMradius)<commit_after>/*
 * Copyright (c) 2013 Opposite Renderer
 * For the full copyright and license information, please view the LICENSE.txt
 * file that was distributed with this source code.
*/

#include "StandaloneRenderManager.hxx"
#include "renderer/PPMOptixRenderer.h"
#include "renderer/PMOptixRenderer.h"
#include <QThread>
#include "renderer/Camera.h"
#include <QTime>
#include "scene/Scene.h"
#include "clientserver/RenderServerRenderRequest.h"
#include <QCoreApplication>
#include <QApplication>
#include "Application.hxx"

StandaloneRenderManager::StandaloneRenderManager(QApplication & qApplication, Application & application, const ComputeDevice& device) :
    m_device(device),
    m_renderer(new PMOptixRenderer()),
    m_nextIterationNumber(0),
    m_outputBuffer(NULL),
    m_currentScene(NULL),
    m_compileScene(false),
    m_application(application),
    m_noEmittedSignals(true),
	m_logger()
{
    connect(&application, SIGNAL(sequenceNumberIncremented()), this, SLOT(onSequenceNumberIncremented()));
    connect(&application, SIGNAL(runningStatusChanged()), this, SLOT(onRunningStatusChanged()));
    connect(&application.getSceneManager(), SIGNAL(sceneLoadingNew()), this, SLOT(onSceneLoadingNew()));
    connect(&application.getSceneManager(), SIGNAL(sceneUpdated()), this, SLOT(onSceneUpdated()));

    onSceneUpdated();

    connect(this, SIGNAL(continueRayTracing()),
            this, SLOT(onContinueRayTracing()),
            Qt::QueuedConnection);
}

SignalLogger& StandaloneRenderManager::logger()
{
	return m_logger;
}

StandaloneRenderManager::~StandaloneRenderManager()
{
    if(m_outputBuffer != NULL)
    {
        delete[] m_outputBuffer;
        m_outputBuffer = NULL;
    }
}

void StandaloneRenderManager::start()
{
    m_application.setRendererStatus(RendererStatus::INITIALIZING_ENGINE);
	m_renderer->initialize(m_device, &m_logger);
}

void StandaloneRenderManager::onContinueRayTracing()
{
    renderNextIteration();
    continueRayTracingIfRunningAsync();
}

void StandaloneRenderManager::renderNextIteration()
{
    try
    {
        if(m_application.getRunningStatus() == RunningStatus::RUNNING && m_currentScene != NULL)
        {
            m_noEmittedSignals = true;

            if(m_compileScene)
            {
                m_application.setRendererStatus(RendererStatus::INITIALIZING_SCENE);
                m_renderer->initScene(*m_currentScene);
                m_compileScene = false;
                m_application.setRendererStatus(RendererStatus::RENDERING);
            }

            const double PPMAlpha = 2.0/3.0;
            QVector<unsigned long long> iterationNumbers;
            QVector<double> ppmRadii;

            RenderServerRenderRequestDetails details (m_camera, QByteArray(m_currentScene->getSceneName()),
                m_application.getRenderMethod(), m_application.getWidth(), m_application.getHeight(), PPMAlpha);

            RenderServerRenderRequest renderRequest (m_application.getSequenceNumber(), iterationNumbers, ppmRadii, details);

            m_renderer->renderNextIteration(0, 0, m_PPMRadius, true, renderRequest.getDetails());

            // Transfer the output buffer to CPU and signal ready for display
            if(m_outputBuffer == NULL)
            {
                m_outputBuffer = new float[2000*2000*3];
            }
            m_renderer->getOutputBuffer(m_outputBuffer);
            emit newFrameReadyForDisplay(m_outputBuffer, m_nextIterationNumber);

            //fillRenderStatistics();
            m_nextIterationNumber++;
			//m_application.setRunningStatus(RunningStatus::PAUSE);
        }
    }
    catch(const std::exception & E)
    {
        m_application.setRunningStatus(RunningStatus::PAUSE);
        QString error = QString("%1").arg(E.what());
        emit renderManagerError(error);
    }
}

/*
unsigned long long StandaloneRenderManager::getIterationNumber() const
{
    return m_nextIterationNumber-1;
}*/

void StandaloneRenderManager::fillRenderStatistics()
{
    m_application.getRenderStatisticsModel().setNumIterations(m_nextIterationNumber);
    m_application.getRenderStatisticsModel().setCurrentPPMRadius(m_PPMRadius);

    if(m_application.getRenderMethod() == RenderMethod::PROGRESSIVE_PHOTON_MAPPING)
    {
        m_application.getRenderStatisticsModel().setNumEmittedPhotonsPerIteration(PMOptixRenderer::EMITTED_PHOTONS_PER_ITERATION);
        m_application.getRenderStatisticsModel().setNumEmittedPhotons(PMOptixRenderer::EMITTED_PHOTONS_PER_ITERATION*m_nextIterationNumber);
    }
    else
    {
        m_application.getRenderStatisticsModel().setNumEmittedPhotonsPerIteration(0);
        m_application.getRenderStatisticsModel().setNumEmittedPhotons(0);

    }

}

// TODO this may be called very often for rapid camera changes.
void StandaloneRenderManager::onSequenceNumberIncremented()
{
    m_nextIterationNumber = 0;
    m_PPMRadius = m_application.getPPMSettingsModel().getPPMInitialRadius();
    m_camera = m_application.getCamera();
    continueRayTracingIfRunningAsync();
}

void StandaloneRenderManager::onSceneLoadingNew()
{
    //m_currentScene = NULL;
}

void StandaloneRenderManager::onSceneUpdated()
{
    IScene* scene = m_application.getSceneManager().getScene();
    if(scene != m_currentScene)
    {
        m_compileScene = true;
        m_currentScene = scene;
    }
}

void StandaloneRenderManager::wait()
{
    printf("StandaloneRenderManager::wait\n");
    /*m_thread->exit();
    m_thread->wait();*/
}

void StandaloneRenderManager::continueRayTracingIfRunningAsync()
{
    if(m_application.getRunningStatus() == RunningStatus::RUNNING && m_noEmittedSignals)
    {
        m_noEmittedSignals = false;
        emit continueRayTracing();
    }
}

void StandaloneRenderManager::onRunningStatusChanged()
{
    continueRayTracingIfRunningAsync();
}<|endoftext|>


<commit_before>// Copyright 2013 Yangqing Jia
// This program converts a set of images to a leveldb by storing them as Datum
// proto buffers.
// Usage:
//    convert_dataset ROOTFOLDER LISTFILE DB_NAME
// where ROOTFOLDER is the root folder that holds all the images, and LISTFILE
// should be a list of files as well as their labels, in the format as
// subfolder1/file1.JPEG 0
// ....

#include <glog/logging.h>
#include <leveldb/db.h>

#include <string>
#include <iostream>
#include <fstream>

#include "caffe/proto/caffe.pb.h"
#include "caffe/util/io.hpp"

using namespace caffe;
using std::string;

// A utility function to generate random strings
void GenerateRandomPrefix(const int n, string* key) {
  const char* kCHARS = "abcdefghijklmnopqrstuvwxyz";
  key->clear();
  for (int i = 0; i < n; ++i) {
    key->push_back(kCHARS[rand() % 26]);
  }
  key->push_back('_');
}

int main(int argc, char** argv) {
  ::google::InitGoogleLogging(argv[0]);
  std::ifstream infile(argv[2]);
  leveldb::DB* db;
  leveldb::Options options;
  options.error_if_exists = true;
  options.create_if_missing = true;
  LOG(INFO) << "Opening leveldb " << argv[3];
  leveldb::Status status = leveldb::DB::Open(
      options, argv[3], &db);
  CHECK(status.ok()) << "Failed to open leveldb " << argv[3];

  string root_folder(argv[1]);
  string filename;
  int label;
  Datum datum;
  string key;
  string value;
  while (infile >> filename >> label) {
    ReadImageToDatum(root_folder + filename, label, &datum);
    // get the key, and add a random string so the leveldb will have permuted
    // data
    GenerateRandomPrefix(8, &key);
    key += filename;
    // get the value
    datum.SerializeToString(&value);
    db->Put(leveldb::WriteOptions(), key, value);
    LOG(ERROR) << "Writing " << key;
  }

  delete db;
  return 0;
}
<commit_msg>scripts to convert dataset<commit_after>// Copyright 2013 Yangqing Jia
// This program converts a set of images to a leveldb by storing them as Datum
// proto buffers.
// Usage:
//    convert_dataset ROOTFOLDER LISTFILE DB_NAME
// where ROOTFOLDER is the root folder that holds all the images, and LISTFILE
// should be a list of files as well as their labels, in the format as
// subfolder1/file1.JPEG 0
// ....
// You are responsible for shuffling the files yourself.

#include <glog/logging.h>
#include <leveldb/db.h>

#include <string>
#include <iostream>
#include <fstream>

#include "caffe/proto/caffe.pb.h"
#include "caffe/util/io.hpp"

using namespace caffe;
using std::string;
using std::stringstream;

// A utility function to generate random strings
void GenerateRandomPrefix(const int n, string* key) {
  const char* kCHARS = "abcdefghijklmnopqrstuvwxyz";
  key->clear();
  for (int i = 0; i < n; ++i) {
    key->push_back(kCHARS[rand() % 26]);
  }
  key->push_back('_');
}

int main(int argc, char** argv) {
  ::google::InitGoogleLogging(argv[0]);
  std::ifstream infile(argv[2]);
  leveldb::DB* db;
  leveldb::Options options;
  options.error_if_exists = true;
  options.create_if_missing = true;
  LOG(INFO) << "Opening leveldb " << argv[3];
  leveldb::Status status = leveldb::DB::Open(
      options, argv[3], &db);
  CHECK(status.ok()) << "Failed to open leveldb " << argv[3];

  string root_folder(argv[1]);
  string filename;
  int label;
  Datum datum;
  int count = 0;
  char key_cstr[100];
  while (infile >> filename >> label) {
    ReadImageToDatum(root_folder + filename, label, &datum);
    sprintf(key_cstr, "%08d_%s", count, filename.c_str());
    string key(key_cstr);
    string value;
    // get the value
    datum.SerializeToString(&value);
    db->Put(leveldb::WriteOptions(), key, value);
    if (++count % 1000 == 0) {
      LOG(ERROR) << "Processed " << count << " files.";
    }
  }

  delete db;
  return 0;
}
<|endoftext|>


<commit_before>#include <cassert>
#include <iostream>
#include <map>
#include <vector>

#include "Helper.h"
#include "Notation.h"

// The number of iterations to do the EM training.
#define NUMBER_ITERATIONS 100

// TODO: Reorganize and use Notation::GIVEN_DELIM. http://bit.ly/15rbAom
#define GIVEN_DELIM "|"
#define AND_DELIM ","
#define SEQ_DELIM ""

using namespace std;

const string X = "X";
const string Y = "Y";
const string A = "A";
const string B = "B";
const vector<string> TAG_LIST{X, Y};
const vector<string> OBSERVED_DATA{A, B, A};
// Enumerate all possible tag sequences for the brute force method.
const vector<string> TAG_SEQUENCES{X+X+X, X+X+Y, X+Y+X, X+Y+Y,
                                   Y+X+X, Y+X+Y, Y+Y+X, Y+Y+Y};

// For output.
vector<double> saved_pABA_results;

// Known probabilities:
Notation pX("P", {X});  // "probability of x"
Notation pY("P", {Y});
Notation pXGivenX("P", {X}, GIVEN_DELIM, {X});
Notation pYGivenX("P", {Y}, GIVEN_DELIM, {X});
Notation pXGivenY("P", {X}, GIVEN_DELIM, {Y});
Notation pYGivenY("P", {Y}, GIVEN_DELIM, {Y});
// Objectives:
Notation pABA("P", {A,B,A}, SEQ_DELIM);
Notation pAGivenX("P", {A}, GIVEN_DELIM, {X});
Notation pAGivenY("P", {A}, GIVEN_DELIM, {Y});
Notation pBGivenX("P", {B}, GIVEN_DELIM, {X});
Notation pBGivenY("P", {B}, GIVEN_DELIM, {Y});
Notation cXA("C", {X, A}, AND_DELIM);  // "count of x and a"
Notation cXB("C", {X, B}, AND_DELIM);
Notation cYA("C", {Y, A}, AND_DELIM);
Notation cYB("C", {Y, B}, AND_DELIM);

void PrepareInitialData(map<string, double> *data) {
  // Given data.
  data->emplace(pX.repr(), .6);
  data->emplace(pY.repr(), .4);
  data->emplace(pXGivenX.repr(), .6);
  data->emplace(pYGivenX.repr(), .4);
  data->emplace(pXGivenY.repr(), .9);
  data->emplace(pYGivenY.repr(), .1);

  // Initial value for unknowns. We improve upon these.
  double initVal = .5;
  data->emplace(pAGivenX.repr(), initVal);
  data->emplace(pAGivenY.repr(), initVal);
  data->emplace(pBGivenX.repr(), initVal);
  data->emplace(pBGivenY.repr(), initVal);
}

void ComputeDataWithBruteForce(map<string, double> *data) {
  saved_pABA_results.push_back((*data)[pABA.repr()]);
  cout << "Initially: \n";
  cout << cXA << ": " << (*data)[cXA.repr()] << endl;
  cout << cXB << ": " << (*data)[cXB.repr()] << endl;
  cout << cYA << ": " << (*data)[cYA.repr()] << endl;
  cout << cYB << ": " << (*data)[cYB.repr()] << endl;
  cout << pABA << ": " << (*data)[pABA.repr()] << endl << endl;

  for (int i = 0; i < NUMBER_ITERATIONS; ++i) {
    cout << "#" << i+1 << ":\n";
    // Reset counts to zero.
    (*data)[cXA.repr()] = 0;
    (*data)[cXB.repr()] = 0;
    (*data)[cYA.repr()] = 0;
    (*data)[cYB.repr()] = 0;

    // Get norm P(t,w) and counts.
    for (string seq : TAG_SEQUENCES) {
      vector<string> tags = NotationHelper::Individualize(seq);
      Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
      double normalizedProb = Calculator::ComputeNormalizedProbability(pTW,
          *data, TAG_LIST.size(), OBSERVED_DATA.size());
      (*data)[pTW.repr()] = normalizedProb;

      // Get counts.
      (*data)[cXA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cXA);
      (*data)[cXB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cXB);
      (*data)[cYA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cYA);
      (*data)[cYB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cYB);
    }
    // Update the unknown probabilities that we want to find. Use them in the
    // next iteration.
    (*data)[pAGivenX.repr()] = (*data)[cXA.repr()]/( (*data)[cXA.repr()] +
        (*data)[cXB.repr()] );
    (*data)[pBGivenX.repr()] = (*data)[cXB.repr()]/( (*data)[cXB.repr()] +
        (*data)[cXA.repr()] );
    (*data)[pAGivenY.repr()] = (*data)[cYA.repr()]/( (*data)[cYA.repr()] +
        (*data)[cYB.repr()] );
    (*data)[pBGivenY.repr()] = (*data)[cYB.repr()]/( (*data)[cYB.repr()] +
        (*data)[cYA.repr()] );

    // The ultimate value we want to maximize. This should increase with each
    // iteration.
    Calculator::UpdateProbOfObsDataSeq(pABA, data, TAG_SEQUENCES);
    cout << "--Summary of iteration " << i+1 << "--\n";
    cout << cXA << ": " << (*data)[cXA.repr()] << endl;
    cout << cXB << ": " << (*data)[cXB.repr()] << endl;
    cout << cYA << ": " << (*data)[cYA.repr()] << endl;
    cout << cYB << ": " << (*data)[cYB.repr()] << endl;
    cout << pAGivenX << ": " << (*data)[pAGivenX.repr()] << endl;
    cout << pBGivenX << ": " << (*data)[pBGivenX.repr()] << endl;
    cout << pAGivenY << ": " << (*data)[pAGivenY.repr()] << endl;
    cout << pBGivenY << ": " << (*data)[pBGivenY.repr()] << endl;
    cout << pABA << ": " << (*data)[pABA.repr()] << endl;
    cout << endl;
    saved_pABA_results.push_back((*data)[pABA.repr()]);
  }
}

int main() {
  map<string, double> data;
  PrepareInitialData(&data);
  ComputeDataWithBruteForce(&data);

  // Goal:
  cout << "--Results based on " << NUMBER_ITERATIONS << " iterations--\n";
  cout << pABA << ": ";
  for (int i = 0; i < saved_pABA_results.size(); ++i) {
    cout << saved_pABA_results[i] << " ";
  }
  cout << endl;
  cout << "Final " << pABA << ": " << data[pABA.repr()] << endl << endl;

  cout << "Determining the best matching tag sequence:\n";
  vector<string> tags = NotationHelper::Individualize(TAG_SEQUENCES[0]);
  Notation pTW_first("P", OBSERVED_DATA, AND_DELIM, tags);
  Notation *best_pTW = NULL;
  string best_match_string_repr = pTW_first.repr();
  for (string seq : TAG_SEQUENCES) {
    vector<string> tags = NotationHelper::Individualize(seq);
    Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
    cout << pTW << ": " << data[pTW.repr()] << endl;
    if (data[pTW.repr()] > data[best_match_string_repr]) {
      best_match_string_repr = pTW.repr();
      delete best_pTW;
      best_pTW = new Notation("P", OBSERVED_DATA, AND_DELIM, tags);
    }
  }
  cout << "The highest probability found belongs to " << best_match_string_repr
    << ": " << data[best_match_string_repr] << endl;
  cout << "The best matching tag sequence is " <<
    NotationHelper::Combine(best_pTW->second) << endl;
  delete best_pTW;

  return 0;
}
<commit_msg>small cleanup of output<commit_after>#include <cassert>
#include <iostream>
#include <map>
#include <vector>

#include "Helper.h"
#include "Notation.h"

// The number of iterations to do the EM training.
#define NUMBER_ITERATIONS 100

// TODO: Reorganize and use Notation::GIVEN_DELIM. http://bit.ly/15rbAom
#define GIVEN_DELIM "|"
#define AND_DELIM ","
#define SEQ_DELIM ""

using namespace std;

const string X = "X";
const string Y = "Y";
const string A = "A";
const string B = "B";
const vector<string> TAG_LIST{X, Y};
const vector<string> OBSERVED_DATA{A, B, A};
// Enumerate all possible tag sequences for the brute force method.
const vector<string> TAG_SEQUENCES{X+X+X, X+X+Y, X+Y+X, X+Y+Y,
                                   Y+X+X, Y+X+Y, Y+Y+X, Y+Y+Y};

// For output.
vector<double> saved_pABA_results;

// Known probabilities:
Notation pX("P", {X});  // "probability of x"
Notation pY("P", {Y});
Notation pXGivenX("P", {X}, GIVEN_DELIM, {X});
Notation pYGivenX("P", {Y}, GIVEN_DELIM, {X});
Notation pXGivenY("P", {X}, GIVEN_DELIM, {Y});
Notation pYGivenY("P", {Y}, GIVEN_DELIM, {Y});
// Objectives:
Notation pABA("P", {A,B,A}, SEQ_DELIM);
Notation pAGivenX("P", {A}, GIVEN_DELIM, {X});
Notation pAGivenY("P", {A}, GIVEN_DELIM, {Y});
Notation pBGivenX("P", {B}, GIVEN_DELIM, {X});
Notation pBGivenY("P", {B}, GIVEN_DELIM, {Y});
Notation cXA("C", {X, A}, AND_DELIM);  // "count of x and a"
Notation cXB("C", {X, B}, AND_DELIM);
Notation cYA("C", {Y, A}, AND_DELIM);
Notation cYB("C", {Y, B}, AND_DELIM);

void PrepareInitialData(map<string, double> *data) {
  // Given data.
  data->emplace(pX.repr(), .6);
  data->emplace(pY.repr(), .4);
  data->emplace(pXGivenX.repr(), .6);
  data->emplace(pYGivenX.repr(), .4);
  data->emplace(pXGivenY.repr(), .9);
  data->emplace(pYGivenY.repr(), .1);

  // Initial value for unknowns. We improve upon these.
  // TODO
  double initVal = .5;
  data->emplace(pAGivenX.repr(), initVal);
  data->emplace(pAGivenY.repr(), initVal);
  data->emplace(pBGivenX.repr(), initVal);
  data->emplace(pBGivenY.repr(), initVal);
}

void ComputeDataWithBruteForce(map<string, double> *data) {
  saved_pABA_results.push_back((*data)[pABA.repr()]); // push back initial 0
  cout << "Initially: \n";
  cout << cXA << ": " << (*data)[cXA.repr()] << endl;
  cout << cXB << ": " << (*data)[cXB.repr()] << endl;
  cout << cYA << ": " << (*data)[cYA.repr()] << endl;
  cout << cYB << ": " << (*data)[cYB.repr()] << endl;
  cout << pABA << ": " << (*data)[pABA.repr()] << endl << endl;

  for (int i = 0; i < NUMBER_ITERATIONS; ++i) {
    cout << "#" << i+1 << ":\n";
    // Reset counts to zero.
    (*data)[cXA.repr()] = 0;
    (*data)[cXB.repr()] = 0;
    (*data)[cYA.repr()] = 0;
    (*data)[cYB.repr()] = 0;

    // Get norm P(t,w) and counts.
    for (string seq : TAG_SEQUENCES) {
      vector<string> tags = NotationHelper::Individualize(seq);
      Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
      double normalizedProb = Calculator::ComputeNormalizedProbability(pTW,
          *data, TAG_LIST.size(), OBSERVED_DATA.size());
      (*data)[pTW.repr()] = normalizedProb;

      // Get counts.
      (*data)[cXA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cXA);
      (*data)[cXB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cXB);
      (*data)[cYA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cYA);
      (*data)[cYB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cYB);
    }
    // Update the unknown probabilities that we want to find. Use them in the
    // next iteration.
    (*data)[pAGivenX.repr()] = (*data)[cXA.repr()]/( (*data)[cXA.repr()] +
        (*data)[cXB.repr()] );
    (*data)[pBGivenX.repr()] = (*data)[cXB.repr()]/( (*data)[cXB.repr()] +
        (*data)[cXA.repr()] );
    (*data)[pAGivenY.repr()] = (*data)[cYA.repr()]/( (*data)[cYA.repr()] +
        (*data)[cYB.repr()] );
    (*data)[pBGivenY.repr()] = (*data)[cYB.repr()]/( (*data)[cYB.repr()] +
        (*data)[cYA.repr()] );

    // The ultimate value we want to maximize. This should increase with each
    // iteration.
    Calculator::UpdateProbOfObsDataSeq(pABA, data, TAG_SEQUENCES);
    cout << "--Summary of iteration " << i+1 << "--\n";
    cout << cXA << ": " << (*data)[cXA.repr()] << endl;
    cout << cXB << ": " << (*data)[cXB.repr()] << endl;
    cout << cYA << ": " << (*data)[cYA.repr()] << endl;
    cout << cYB << ": " << (*data)[cYB.repr()] << endl;
    cout << pAGivenX << ": " << (*data)[pAGivenX.repr()] << endl;
    cout << pBGivenX << ": " << (*data)[pBGivenX.repr()] << endl;
    cout << pAGivenY << ": " << (*data)[pAGivenY.repr()] << endl;
    cout << pBGivenY << ": " << (*data)[pBGivenY.repr()] << endl;
    cout << pABA << ": " << (*data)[pABA.repr()] << endl;
    cout << endl;
    saved_pABA_results.push_back((*data)[pABA.repr()]);
  }
}

int main() {
  map<string, double> data;
  PrepareInitialData(&data);
  ComputeDataWithBruteForce(&data);

  // Goal:
  cout << "--Results based on " << NUMBER_ITERATIONS << " iterations--\n";
  cout << pABA << ": ";
  for (int i = 0; i < saved_pABA_results.size(); ++i) {
    cout << saved_pABA_results[i] << " ";
  }
  cout << endl;
  cout << "Final " << pABA << ": " << data[pABA.repr()] << endl << endl;

  cout << "Determining the best matching tag sequence:\n";
  vector<string> tags = NotationHelper::Individualize(TAG_SEQUENCES[0]);
  Notation pTW_first("P", OBSERVED_DATA, AND_DELIM, tags);
  Notation *best_pTGivenW = NULL;
  string best_match_string_repr = pTW_first.repr();
  for (string seq : TAG_SEQUENCES) {
    vector<string> tags = NotationHelper::Individualize(seq);
    Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);

    // Compute P(t|w). Technically not used because divided values seem to
    // incorrectly yield >1 (decimals too small, possibly).
    Notation pTGivenW("P", tags, GIVEN_DELIM, OBSERVED_DATA);
    data[pTGivenW.repr()] = data[pTW.repr()] / data[pABA.repr()];
    cout << pTW << ": " << data[pTW.repr()] << endl; // ", " << pTGivenW << ": " <<
    //  data[pTGivenW.repr()] << endl;
    if (data[pTW.repr()] > data[best_match_string_repr]) {
      best_match_string_repr = pTW.repr();
      delete best_pTGivenW;
      // Same as pTGivenW.
      best_pTGivenW = new Notation("P", tags, GIVEN_DELIM, OBSERVED_DATA);
    }
  }
  string pTAndWRepr = best_match_string_repr;
  cout << "The highest probability found belongs to " << pTAndWRepr << ": " <<
    data[pTAndWRepr] << endl;
  cout << "The best matching tag sequence is " <<
    NotationHelper::Combine(best_pTGivenW->first) << endl;
  delete best_pTGivenW;

  return 0;
}
<|endoftext|>


<commit_before>#include "musicsongtag.h"
#include "musictime.h"
#include "musicformats.h"
#include "musicversion.h"
#include "musiccoreutils.h"
#include "musicwidgetutils.h"

#include <QStringList>
#include <QPluginLoader>
#include <QFileInfo>
///qmmp incldue
#include "tagreadandwrite.h"
#include "decoderfactory.h"
#include "metadatamodel.h"
#include "decoder.h"

MusicSongTag::MusicSongTag()
{

}

MusicSongTag::MusicSongTag(const QString &file)
    : MusicSongTag()
{
    read(file);
}

QString MusicSongTag::getClassName()
{
    return "MusicSongTag";
}

bool MusicSongTag::read(const QString &file)
{
    QFile f(file);
    if(!f.exists() || f.size() <= 0)
    {
        return false;
    }

    m_filePath = file;
    return readOtherTaglib();
}

bool MusicSongTag::save()
{
    return saveOtherTaglib();
}

QString MusicSongTag::getDecoder() const
{
    QString v = findPluginPath();
    return QFileInfo(v).baseName();
}

QString MusicSongTag::getFilePath() const
{
    return m_filePath;
}

QString MusicSongTag::getArtist() const
{
    return m_parameters[TagReadAndWrite::TAG_ARTIST].toString();
}

QString MusicSongTag::getTitle() const
{
    return m_parameters[TagReadAndWrite::TAG_TITLE].toString();
}

QString MusicSongTag::getAlbum() const
{
    return m_parameters[TagReadAndWrite::TAG_ALBUM].toString();
}

QString MusicSongTag::getComment() const
{
    return m_parameters[TagReadAndWrite::TAG_COMMENT].toString();
}

QString MusicSongTag::getYear() const
{
    return m_parameters[TagReadAndWrite::TAG_YEAR].toString();
}

QString MusicSongTag::getTrackNum() const
{
    QString v = m_parameters[TagReadAndWrite::TAG_TRACK].toString();
    bool ok = true;
    if(v.toInt(&ok) > 0)
    {
        return !ok ? "-" : v;
    }
    return "-";
}

QString MusicSongTag::getGenre() const
{
    return m_parameters[TagReadAndWrite::TAG_GENRE].toString();
}

QString MusicSongTag::getAlbumArtist() const
{
    return m_parameters[TagReadAndWrite::TAG_ALBUMARTIST].toString();
}

QString MusicSongTag::getComposer() const
{
    return m_parameters[TagReadAndWrite::TAG_COMPOSER].toString();
}

QString MusicSongTag::getChannel() const
{
    return m_parameters[TagReadAndWrite::TAG_CHANNEL].toString();
}

QString MusicSongTag::getURL() const
{
    return m_parameters[TagReadAndWrite::TAG_URL].toString();
}

/////////////////////////////////////////////
void MusicSongTag::setArtist(const QString &artist)
{
    m_parameters[TagReadAndWrite::TAG_ARTIST] = artist;
}

void MusicSongTag::setTitle(const QString &title)
{
    m_parameters[TagReadAndWrite::TAG_TITLE] = title;
}

void MusicSongTag::setAlbum(const QString &album)
{
    m_parameters[TagReadAndWrite::TAG_ALBUM] = album;
}

void MusicSongTag::setComment(const QString &comment)
{
    m_parameters[TagReadAndWrite::TAG_COMMENT] = comment;
}

void MusicSongTag::setYear(const QString &year)
{
    m_parameters[TagReadAndWrite::TAG_YEAR] = year;
}

void MusicSongTag::setTrackNum(const QString &track)
{
    m_parameters[TagReadAndWrite::TAG_TRACK] = track;
}

void MusicSongTag::setGenre(const QString &genre)
{
    m_parameters[TagReadAndWrite::TAG_GENRE] = genre;
}

void MusicSongTag::setCover(const QPixmap &pix)
{
#if TTKMUSIC_VERSION >= TTKMUSIC_VERSION_CHECK(2,5,3,0)
    m_parameters[TagReadAndWrite::TAG_COVER] = pix;
#else
    Q_UNUSED(data);
#endif
}

void MusicSongTag::setCover(const QByteArray &data)
{
#if TTKMUSIC_VERSION >= TTKMUSIC_VERSION_CHECK(2,5,3,0)
    QPixmap pix;
    pix.loadFromData(data);
    m_parameters[TagReadAndWrite::TAG_COVER] = pix;
#else
    Q_UNUSED(data);
#endif
}

QPixmap MusicSongTag::getCover() const
{
#if TTKMUSIC_VERSION >= TTKMUSIC_VERSION_CHECK(2,5,3,0)
    return m_parameters[TagReadAndWrite::TAG_COVER].value<QPixmap>();
#else
    return QPixmap();
#endif
}

/////////////////////////////////////////////
QString MusicSongTag::getSamplingRate() const
{
    return m_parameters[TagReadAndWrite::TAG_SAMPLERATE].toString();
}

QString MusicSongTag::getFormat() const
{
    return m_parameters[TagReadAndWrite::TAG_FORMAT].toString();
}

QString MusicSongTag::getMode() const
{
    return m_parameters[TagReadAndWrite::TAG_MODE].toString();
}

QString MusicSongTag::getBitrate() const
{
    return m_parameters[TagReadAndWrite::TAG_BITRATE].toString();
}

QString MusicSongTag::getLengthString() const
{
    return MusicTime::msecTime2LabelJustified(
           m_parameters[TagReadAndWrite::TAG_LENGTH].toULongLong());
}

QString MusicSongTag::findPluginPath() const
{
    QString suffix = QFileInfo(m_filePath).suffix().toLower();

    MusicObject::MStringsListMap formats(MusicFormats::supportFormatsStringMap());
    foreach(const QString &key, formats.keys())
    {
        if(formats.value(key).contains(suffix))
        {
            return MusicUtils::Core::pluginPath("Input", key);
        }
    }

    return QString();
}

bool MusicSongTag::readOtherTaglib()
{
    QPluginLoader loader;
    loader.setFileName(findPluginPath());

    QObject *obj = loader.instance();
    DecoderFactory *decoderfac = nullptr;
    if(obj && (decoderfac = MObject_cast(DecoderFactory*, obj)) )
    {
        int length = 0;
        MetaDataModel *model = decoderfac->createMetaDataModel(m_filePath);
        if(model != nullptr)
        {
            QHash<QString, QString> datas = model->audioProperties();
            MusicTime t = MusicTime::fromString(datas.value("Length"), QString("m:ss"));
            length = t.getTimeStamp(MusicTime::All_Msec);
            if(length != 0)
            {
                m_parameters.insert(TagReadAndWrite::TAG_LENGTH, QString::number(length));
            }
            m_parameters.insert(TagReadAndWrite::TAG_SAMPLERATE, datas.value("Sample rate"));
            m_parameters.insert(TagReadAndWrite::TAG_BITRATE, datas.value("Bitrate"));
            m_parameters.insert(TagReadAndWrite::TAG_CHANNEL, datas.value("Channels"));

            m_parameters.insert(TagReadAndWrite::TAG_COVER, model->cover());

            QList<TagModel* > tags = model->tags();
            if(!tags.isEmpty())
            {
                TagModel *tagModel = tags.first();
                if(tags.count() == 3)
                {
                    tagModel = tags[1]; //id3v2 mode tag
                }

                m_parameters[TagReadAndWrite::TAG_TITLE] = tagModel->value(Qmmp::TITLE);
                m_parameters[TagReadAndWrite::TAG_ARTIST] = tagModel->value(Qmmp::ARTIST);
                m_parameters[TagReadAndWrite::TAG_ALBUM] = tagModel->value(Qmmp::ALBUM);
                m_parameters[TagReadAndWrite::TAG_YEAR] = tagModel->value(Qmmp::YEAR);
                m_parameters[TagReadAndWrite::TAG_COMMENT] = tagModel->value(Qmmp::COMMENT);
                m_parameters[TagReadAndWrite::TAG_TRACK] = tagModel->value(Qmmp::TRACK);
                m_parameters[TagReadAndWrite::TAG_GENRE] = tagModel->value(Qmmp::GENRE);
            }
        }

        if(length == 0)
        {
            QList<FileInfo*> infos(decoderfac->createPlayList(m_filePath, true, 0));
            if(!infos.isEmpty())
            {
                length = infos.first()->length()*MT_S2MS;
            }
            qDeleteAll(infos);

            if(length == 0)
            {
                TagReadAndWrite tag;
                if(tag.readFile(m_filePath))
                {
                    QMap<TagReadAndWrite::MusicTag, QString> data = tag.getMusicTags();
                    length = data[TagReadAndWrite::TAG_LENGTH].toInt();
                }
            }

            m_parameters[TagReadAndWrite::TAG_LENGTH] = QString::number(length);
        }

        delete model;
        loader.unload();
    }

    return !m_parameters.isEmpty();
}

bool MusicSongTag::saveOtherTaglib()
{
    QPluginLoader loader;
    loader.setFileName(findPluginPath());

    bool status = false;
    QObject *obj = loader.instance();
    DecoderFactory *decoderfac = nullptr;
    if(obj && (decoderfac = MObject_cast(DecoderFactory*, obj)) )
    {
        status = true;
        MetaDataModel *model = decoderfac->createMetaDataModel(m_filePath);
        if(model)
        {
            QList<TagModel* > tags = model->tags();
            if(!tags.isEmpty())
            {
                TagModel *tagModel = tags.first();
                if(tags.count() == 3)
                {
                    tagModel = tags[1]; //id3v2 mode tag
                }

                tagModel->setValue(Qmmp::ALBUM, getAlbum());
                tagModel->setValue(Qmmp::ARTIST, getArtist());
                tagModel->setValue(Qmmp::TITLE, getTitle());
                tagModel->setValue(Qmmp::YEAR, getYear());
                tagModel->setValue(Qmmp::GENRE, getGenre());
                tagModel->save();
            }

            ////////////////////////////////////////////////////////////////////
            model->setCover(MusicUtils::Widget::getPixmapData(getCover()));
            ////////////////////////////////////////////////////////////////////
        }
        delete model;
        loader.unload();
    }

    return status;
}
<commit_msg>Skip the empty pixmap[016223]<commit_after>#include "musicsongtag.h"
#include "musictime.h"
#include "musicformats.h"
#include "musicversion.h"
#include "musiccoreutils.h"
#include "musicwidgetutils.h"

#include <QStringList>
#include <QPluginLoader>
#include <QFileInfo>
///qmmp incldue
#include "tagreadandwrite.h"
#include "decoderfactory.h"
#include "metadatamodel.h"
#include "decoder.h"

MusicSongTag::MusicSongTag()
{

}

MusicSongTag::MusicSongTag(const QString &file)
    : MusicSongTag()
{
    read(file);
}

QString MusicSongTag::getClassName()
{
    return "MusicSongTag";
}

bool MusicSongTag::read(const QString &file)
{
    QFile f(file);
    if(!f.exists() || f.size() <= 0)
    {
        return false;
    }

    m_filePath = file;
    return readOtherTaglib();
}

bool MusicSongTag::save()
{
    return saveOtherTaglib();
}

QString MusicSongTag::getDecoder() const
{
    QString v = findPluginPath();
    return QFileInfo(v).baseName();
}

QString MusicSongTag::getFilePath() const
{
    return m_filePath;
}

QString MusicSongTag::getArtist() const
{
    return m_parameters[TagReadAndWrite::TAG_ARTIST].toString();
}

QString MusicSongTag::getTitle() const
{
    return m_parameters[TagReadAndWrite::TAG_TITLE].toString();
}

QString MusicSongTag::getAlbum() const
{
    return m_parameters[TagReadAndWrite::TAG_ALBUM].toString();
}

QString MusicSongTag::getComment() const
{
    return m_parameters[TagReadAndWrite::TAG_COMMENT].toString();
}

QString MusicSongTag::getYear() const
{
    return m_parameters[TagReadAndWrite::TAG_YEAR].toString();
}

QString MusicSongTag::getTrackNum() const
{
    QString v = m_parameters[TagReadAndWrite::TAG_TRACK].toString();
    bool ok = true;
    if(v.toInt(&ok) > 0)
    {
        return !ok ? "-" : v;
    }
    return "-";
}

QString MusicSongTag::getGenre() const
{
    return m_parameters[TagReadAndWrite::TAG_GENRE].toString();
}

QString MusicSongTag::getAlbumArtist() const
{
    return m_parameters[TagReadAndWrite::TAG_ALBUMARTIST].toString();
}

QString MusicSongTag::getComposer() const
{
    return m_parameters[TagReadAndWrite::TAG_COMPOSER].toString();
}

QString MusicSongTag::getChannel() const
{
    return m_parameters[TagReadAndWrite::TAG_CHANNEL].toString();
}

QString MusicSongTag::getURL() const
{
    return m_parameters[TagReadAndWrite::TAG_URL].toString();
}

/////////////////////////////////////////////
void MusicSongTag::setArtist(const QString &artist)
{
    m_parameters[TagReadAndWrite::TAG_ARTIST] = artist;
}

void MusicSongTag::setTitle(const QString &title)
{
    m_parameters[TagReadAndWrite::TAG_TITLE] = title;
}

void MusicSongTag::setAlbum(const QString &album)
{
    m_parameters[TagReadAndWrite::TAG_ALBUM] = album;
}

void MusicSongTag::setComment(const QString &comment)
{
    m_parameters[TagReadAndWrite::TAG_COMMENT] = comment;
}

void MusicSongTag::setYear(const QString &year)
{
    m_parameters[TagReadAndWrite::TAG_YEAR] = year;
}

void MusicSongTag::setTrackNum(const QString &track)
{
    m_parameters[TagReadAndWrite::TAG_TRACK] = track;
}

void MusicSongTag::setGenre(const QString &genre)
{
    m_parameters[TagReadAndWrite::TAG_GENRE] = genre;
}

void MusicSongTag::setCover(const QPixmap &pix)
{
#if TTKMUSIC_VERSION >= TTKMUSIC_VERSION_CHECK(2,5,3,0)
    m_parameters[TagReadAndWrite::TAG_COVER] = pix;
#else
    Q_UNUSED(data);
#endif
}

void MusicSongTag::setCover(const QByteArray &data)
{
#if TTKMUSIC_VERSION >= TTKMUSIC_VERSION_CHECK(2,5,3,0)
    QPixmap pix;
    pix.loadFromData(data);
    m_parameters[TagReadAndWrite::TAG_COVER] = pix;
#else
    Q_UNUSED(data);
#endif
}

QPixmap MusicSongTag::getCover() const
{
#if TTKMUSIC_VERSION >= TTKMUSIC_VERSION_CHECK(2,5,3,0)
    return m_parameters[TagReadAndWrite::TAG_COVER].value<QPixmap>();
#else
    return QPixmap();
#endif
}

/////////////////////////////////////////////
QString MusicSongTag::getSamplingRate() const
{
    return m_parameters[TagReadAndWrite::TAG_SAMPLERATE].toString();
}

QString MusicSongTag::getFormat() const
{
    return m_parameters[TagReadAndWrite::TAG_FORMAT].toString();
}

QString MusicSongTag::getMode() const
{
    return m_parameters[TagReadAndWrite::TAG_MODE].toString();
}

QString MusicSongTag::getBitrate() const
{
    return m_parameters[TagReadAndWrite::TAG_BITRATE].toString();
}

QString MusicSongTag::getLengthString() const
{
    return MusicTime::msecTime2LabelJustified(
           m_parameters[TagReadAndWrite::TAG_LENGTH].toULongLong());
}

QString MusicSongTag::findPluginPath() const
{
    QString suffix = QFileInfo(m_filePath).suffix().toLower();

    MusicObject::MStringsListMap formats(MusicFormats::supportFormatsStringMap());
    foreach(const QString &key, formats.keys())
    {
        if(formats.value(key).contains(suffix))
        {
            return MusicUtils::Core::pluginPath("Input", key);
        }
    }

    return QString();
}

bool MusicSongTag::readOtherTaglib()
{
    QPluginLoader loader;
    loader.setFileName(findPluginPath());

    QObject *obj = loader.instance();
    DecoderFactory *decoderfac = nullptr;
    if(obj && (decoderfac = MObject_cast(DecoderFactory*, obj)) )
    {
        int length = 0;
        MetaDataModel *model = decoderfac->createMetaDataModel(m_filePath);
        if(model != nullptr)
        {
            QHash<QString, QString> datas = model->audioProperties();
            MusicTime t = MusicTime::fromString(datas.value("Length"), QString("m:ss"));
            length = t.getTimeStamp(MusicTime::All_Msec);
            if(length != 0)
            {
                m_parameters.insert(TagReadAndWrite::TAG_LENGTH, QString::number(length));
            }
            m_parameters.insert(TagReadAndWrite::TAG_SAMPLERATE, datas.value("Sample rate"));
            m_parameters.insert(TagReadAndWrite::TAG_BITRATE, datas.value("Bitrate"));
            m_parameters.insert(TagReadAndWrite::TAG_CHANNEL, datas.value("Channels"));

            m_parameters.insert(TagReadAndWrite::TAG_COVER, model->cover());

            QList<TagModel* > tags = model->tags();
            if(!tags.isEmpty())
            {
                TagModel *tagModel = tags.first();
                if(tags.count() == 3)
                {
                    tagModel = tags[1]; //id3v2 mode tag
                }

                m_parameters[TagReadAndWrite::TAG_TITLE] = tagModel->value(Qmmp::TITLE);
                m_parameters[TagReadAndWrite::TAG_ARTIST] = tagModel->value(Qmmp::ARTIST);
                m_parameters[TagReadAndWrite::TAG_ALBUM] = tagModel->value(Qmmp::ALBUM);
                m_parameters[TagReadAndWrite::TAG_YEAR] = tagModel->value(Qmmp::YEAR);
                m_parameters[TagReadAndWrite::TAG_COMMENT] = tagModel->value(Qmmp::COMMENT);
                m_parameters[TagReadAndWrite::TAG_TRACK] = tagModel->value(Qmmp::TRACK);
                m_parameters[TagReadAndWrite::TAG_GENRE] = tagModel->value(Qmmp::GENRE);
            }
        }

        if(length == 0)
        {
            QList<FileInfo*> infos(decoderfac->createPlayList(m_filePath, true, 0));
            if(!infos.isEmpty())
            {
                length = infos.first()->length()*MT_S2MS;
            }
            qDeleteAll(infos);

            if(length == 0)
            {
                TagReadAndWrite tag;
                if(tag.readFile(m_filePath))
                {
                    QMap<TagReadAndWrite::MusicTag, QString> data = tag.getMusicTags();
                    length = data[TagReadAndWrite::TAG_LENGTH].toInt();
                }
            }

            m_parameters[TagReadAndWrite::TAG_LENGTH] = QString::number(length);
        }

        delete model;
        loader.unload();
    }

    return !m_parameters.isEmpty();
}

bool MusicSongTag::saveOtherTaglib()
{
    QPluginLoader loader;
    loader.setFileName(findPluginPath());

    bool status = false;
    QObject *obj = loader.instance();
    DecoderFactory *decoderfac = nullptr;
    if(obj && (decoderfac = MObject_cast(DecoderFactory*, obj)) )
    {
        status = true;
        MetaDataModel *model = decoderfac->createMetaDataModel(m_filePath);
        if(model)
        {
            QList<TagModel* > tags = model->tags();
            if(!tags.isEmpty())
            {
                TagModel *tagModel = tags.first();
                if(tags.count() == 3)
                {
                    tagModel = tags[1]; //id3v2 mode tag
                }

                tagModel->setValue(Qmmp::ALBUM, getAlbum());
                tagModel->setValue(Qmmp::ARTIST, getArtist());
                tagModel->setValue(Qmmp::TITLE, getTitle());
                tagModel->setValue(Qmmp::YEAR, getYear());
                tagModel->setValue(Qmmp::GENRE, getGenre());
                tagModel->save();
            }

            ////////////////////////////////////////////////////////////////////
            QPixmap pix = getCover();
            if(!pix.isNull())
            {
                model->setCover(MusicUtils::Widget::getPixmapData(pix));
            }
            ////////////////////////////////////////////////////////////////////
        }
        delete model;
        loader.unload();
    }

    return status;
}
<|endoftext|>


<commit_before>#include <cassert>
#include <iostream>
#include <fstream>
#include <map>
#include <vector>

#include "NLPHelper.h"
#include "Notation.h"

/*  SETTINGS  */
// The number of iterations to do the EM training.
#define NUMBER_ITERATIONS 100

// Two ways to run this program: with a short or a long observed sequence.
#define DO_SHORT_SEQ true
/*  END SETTINGS  */

// TODO: Reorganize and use Notation::GIVEN_DELIM. http://bit.ly/15rbAom
#define GIVEN_DELIM "|"
#define AND_DELIM ","
#define SEQ_DELIM ""

using namespace std;

const string X = "X";
const string Y = "Y";
const string A = "A";
const string B = "B";
const vector<string> TAG_LIST{X, Y};
#if DO_SHORT_SEQ
const vector<string> OBSERVED_DATA{A, B, A};
#else
const vector<string> OBSERVED_DATA{A,A,A,B,A,A,B,A,A};
#endif

// For output. Saves the changing values of pABA (or the longer seq).
vector<double> saved_obs_seq_probs;

// Known probabilities:
Notation pX("P", {X});  // "probability of x"
Notation pY("P", {Y});
Notation pXGivenX("P", {X}, GIVEN_DELIM, {X});
Notation pYGivenX("P", {Y}, GIVEN_DELIM, {X});
Notation pXGivenY("P", {X}, GIVEN_DELIM, {Y});
Notation pYGivenY("P", {Y}, GIVEN_DELIM, {Y});
// Objectives:
// Short seq type.
Notation pABA("P", {A,B,A}, SEQ_DELIM);
Notation pAGivenX("P", {A}, GIVEN_DELIM, {X});
Notation pAGivenY("P", {A}, GIVEN_DELIM, {Y});
Notation pBGivenX("P", {B}, GIVEN_DELIM, {X});
Notation pBGivenY("P", {B}, GIVEN_DELIM, {Y});
Notation cXA("C", {X, A}, AND_DELIM);  // "count of x and a"
Notation cXB("C", {X, B}, AND_DELIM);
Notation cYA("C", {Y, A}, AND_DELIM);
Notation cYB("C", {Y, B}, AND_DELIM);
// Long seq type.
Notation pLong("P", {A,A,A,B,A,A,B,A,A}, SEQ_DELIM);

void PrepareInitialData(map<string, double> *data) {
  // Given data.
  data->emplace(pX.repr(), .6);
  data->emplace(pY.repr(), .4);
  data->emplace(pXGivenX.repr(), .6);
  data->emplace(pYGivenX.repr(), .4);
  data->emplace(pXGivenY.repr(), .9);
  data->emplace(pYGivenY.repr(), .1);

  // Initial value for unknowns. We improve upon these.
  double initVal = .5;
  data->emplace(pAGivenX.repr(), initVal);
  data->emplace(pAGivenY.repr(), initVal);
  data->emplace(pBGivenX.repr(), initVal);
  data->emplace(pBGivenY.repr(), initVal);

  // Initial counts can be set to 0.
  data->emplace(cXA.repr(), 0);
  data->emplace(cYA.repr(), 0);
  data->emplace(cXB.repr(), 0);
  data->emplace(cYB.repr(), 0);
}

void ComputeDataWithBruteForce(map<string, double> *data, const Notation &n,
                               const vector<string> &tag_sequences) {
  saved_obs_seq_probs.push_back((*data)[n.repr()]); // push back initial 0

  vector<Notation> rowOfNots{cXA, cXB, pAGivenX, pBGivenX, cYA, cYB, pAGivenY,
    pBGivenY, n};
  OutputHelper::PrintHeader(rowOfNots);
  OutputHelper::PrintDataRow(0, rowOfNots, *data);

  for (int i = 0; i < NUMBER_ITERATIONS; ++i) {
    // Reset counts to zero.
    (*data)[cXA.repr()] = 0;
    (*data)[cXB.repr()] = 0;
    (*data)[cYA.repr()] = 0;
    (*data)[cYB.repr()] = 0;

    // Get norm P(t,w) and counts.
    for (string seq : tag_sequences) {
      vector<string> tags = NotationHelper::Individualize(seq);
      Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
      double normalizedProb = Calculator::ComputeNormalizedProbability(pTW,
          *data, TAG_LIST.size(), OBSERVED_DATA.size());
      (*data)[pTW.repr()] = normalizedProb;

      // Get counts.
      (*data)[cXA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cXA);
      (*data)[cXB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cXB);
      (*data)[cYA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cYA);
      (*data)[cYB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cYB);
    }
    // Update the unknown probabilities that we want to find. Use them in the
    // next iteration.
    (*data)[pAGivenX.repr()] = (*data)[cXA.repr()]/( (*data)[cXA.repr()] +
        (*data)[cXB.repr()] );
    (*data)[pBGivenX.repr()] = (*data)[cXB.repr()]/( (*data)[cXB.repr()] +
        (*data)[cXA.repr()] );
    (*data)[pAGivenY.repr()] = (*data)[cYA.repr()]/( (*data)[cYA.repr()] +
        (*data)[cYB.repr()] );
    (*data)[pBGivenY.repr()] = (*data)[cYB.repr()]/( (*data)[cYB.repr()] +
        (*data)[cYA.repr()] );

    // The ultimate value we want to maximize. This should increase with each
    // iteration.
    Calculator::UpdateProbOfObsDataSeq(n, data, tag_sequences);
    saved_obs_seq_probs.push_back((*data)[n.repr()]);
    OutputHelper::PrintDataRow(i + 1, rowOfNots, *data);
  }
}

void OutputResults(map<string, double> &data, Notation n, const vector<string>
                   &tag_sequences) {
  cout << "\n--Results based on " << NUMBER_ITERATIONS << " iterations--\n";
  ofstream fout("observed_data_probabilities.txt");
  for (int i = 0; i < saved_obs_seq_probs.size(); ++i) {
    fout << saved_obs_seq_probs[i] << endl;
  }
  cout << "Values of " << n << " have been written to "
    "observed_data_probabilities.txt." << endl << endl;

  cout << "Final " << n << ": " << data[n.repr()] << endl;
  cout << "Final " << pAGivenX << ": " << data[pAGivenX.repr()] << endl;
  cout << "Final " << pBGivenX << ": " << data[pBGivenX.repr()] << endl;
  cout << "Final " << pAGivenY << ": " << data[pAGivenY.repr()] << endl;
  cout << "Final " << pBGivenY << ": " << data[pBGivenY.repr()] << endl << endl;

  cout << "Determining the best matching tag sequence:\n";
  vector<string> tags = NotationHelper::Individualize(tag_sequences.at(0));
  Notation pTW_first("P", OBSERVED_DATA, AND_DELIM, tags);
  Notation *best_pTGivenW = NULL;
  string best_match_string_repr = pTW_first.repr();
  for (string seq : tag_sequences) {
    vector<string> tags = NotationHelper::Individualize(seq);
    Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
    Notation pTGivenW("P", tags, GIVEN_DELIM, OBSERVED_DATA);
    // Compute P(t|w). Technically not used because divided values seem to
    // incorrectly yield >1 (decimals too small, possibly).
    data[pTGivenW.repr()] = data[pTW.repr()] / data[n.repr()];
    if (DO_SHORT_SEQ) { // Only print for short seq; long seq has too many.
      cout << pTW << ": " << data[pTW.repr()] << endl;
    }
    if (data[pTW.repr()] > data[best_match_string_repr]) {
      best_match_string_repr = pTW.repr();
      delete best_pTGivenW;
      // Same as pTGivenW.
      best_pTGivenW = new Notation("P", tags, GIVEN_DELIM, OBSERVED_DATA);
    }
  }
  string pTAndWRepr = best_match_string_repr;
  cout << "The highest probability found belongs to " << pTAndWRepr << ": " <<
    data[pTAndWRepr] << endl;
  cout << "The best matching tag sequence is " <<
    NotationHelper::Combine(best_pTGivenW->first) << endl;
  delete best_pTGivenW;
}

int main() {
  map<string, double> data;
  PrepareInitialData(&data);
  vector<string> tag_sequences = TagHandler::GenerateTagSequences(TAG_LIST,
      OBSERVED_DATA.size());
  if (DO_SHORT_SEQ) {
    ComputeDataWithBruteForce(&data, pABA, tag_sequences);
    OutputResults(data, pABA, tag_sequences);
  } else {
    ComputeDataWithBruteForce(&data, pLong, tag_sequences);
    OutputResults(data, pLong, tag_sequences);
  }
  return 0;
}
<commit_msg>created options for initial values<commit_after>#include <cassert>
#include <iostream>
#include <fstream>
#include <map>
#include <vector>

#include "NLPHelper.h"
#include "Notation.h"

/*  SETTINGS  */
// The number of iterations to do the EM training.
#define NUMBER_ITERATIONS 100

// Two ways to run this program: with a short or a long observed sequence.
#define DO_SHORT_SEQ false

// Initial values.
#define INIT_VAL_pAGivenX .5
#define INIT_VAL_pAGivenY .5
#define INIT_VAL_pBGivenX .5
#define INIT_VAL_pBGivenY .5
/*  END SETTINGS  */

// TODO: Reorganize and use Notation::GIVEN_DELIM. http://bit.ly/15rbAom
#define GIVEN_DELIM "|"
#define AND_DELIM ","
#define SEQ_DELIM ""

using namespace std;

const string X = "X";
const string Y = "Y";
const string A = "A";
const string B = "B";
const vector<string> TAG_LIST{X, Y};
#if DO_SHORT_SEQ
const vector<string> OBSERVED_DATA{A, B, A};
#else
const vector<string> OBSERVED_DATA{A,A,A,B,A,A,B,A,A};
#endif

// For output. Saves the changing values of pABA (or the longer seq).
vector<double> saved_obs_seq_probs;

// Known probabilities:
Notation pX("P", {X});  // "probability of x"
Notation pY("P", {Y});
Notation pXGivenX("P", {X}, GIVEN_DELIM, {X});
Notation pYGivenX("P", {Y}, GIVEN_DELIM, {X});
Notation pXGivenY("P", {X}, GIVEN_DELIM, {Y});
Notation pYGivenY("P", {Y}, GIVEN_DELIM, {Y});
// Objectives:
// Short seq type.
Notation pABA("P", {A,B,A}, SEQ_DELIM);
Notation pAGivenX("P", {A}, GIVEN_DELIM, {X});
Notation pAGivenY("P", {A}, GIVEN_DELIM, {Y});
Notation pBGivenX("P", {B}, GIVEN_DELIM, {X});
Notation pBGivenY("P", {B}, GIVEN_DELIM, {Y});
Notation cXA("C", {X, A}, AND_DELIM);  // "count of x and a"
Notation cXB("C", {X, B}, AND_DELIM);
Notation cYA("C", {Y, A}, AND_DELIM);
Notation cYB("C", {Y, B}, AND_DELIM);
// Long seq type.
Notation pLong("P", {A,A,A,B,A,A,B,A,A}, SEQ_DELIM);

void PrepareInitialData(map<string, double> *data) {
  // Given data.
  data->emplace(pX.repr(), .6);
  data->emplace(pY.repr(), .4);
  data->emplace(pXGivenX.repr(), .6);
  data->emplace(pYGivenX.repr(), .4);
  data->emplace(pXGivenY.repr(), .9);
  data->emplace(pYGivenY.repr(), .1);

  // Initial value for unknowns. We improve upon these.
  data->emplace(pAGivenX.repr(), INIT_VAL_pAGivenX);
  data->emplace(pAGivenY.repr(), INIT_VAL_pAGivenY);
  data->emplace(pBGivenX.repr(), INIT_VAL_pBGivenX);
  data->emplace(pBGivenY.repr(), INIT_VAL_pBGivenY);

  // Initial counts can be set to 0.
  data->emplace(cXA.repr(), 0);
  data->emplace(cYA.repr(), 0);
  data->emplace(cXB.repr(), 0);
  data->emplace(cYB.repr(), 0);
}

void ComputeDataWithBruteForce(map<string, double> *data, const Notation &n,
                               const vector<string> &tag_sequences) {
  saved_obs_seq_probs.push_back((*data)[n.repr()]); // push back initial 0

  vector<Notation> rowOfNots{cXA, cXB, pAGivenX, pBGivenX, cYA, cYB, pAGivenY,
    pBGivenY, n};
  OutputHelper::PrintHeader(rowOfNots);
  OutputHelper::PrintDataRow(0, rowOfNots, *data);

  for (int i = 0; i < NUMBER_ITERATIONS; ++i) {
    // Reset counts to zero.
    (*data)[cXA.repr()] = 0;
    (*data)[cXB.repr()] = 0;
    (*data)[cYA.repr()] = 0;
    (*data)[cYB.repr()] = 0;

    // Get norm P(t,w) and counts.
    for (string seq : tag_sequences) {
      vector<string> tags = NotationHelper::Individualize(seq);
      Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
      double normalizedProb = Calculator::ComputeNormalizedProbability(pTW,
          *data, TAG_LIST.size(), OBSERVED_DATA.size());
      (*data)[pTW.repr()] = normalizedProb;

      // Get counts.
      (*data)[cXA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cXA);
      (*data)[cXB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cXB);
      (*data)[cYA.repr()] += Calculator::NormProbFactor(normalizedProb, pTW,
          cYA);
      (*data)[cYB.repr()] +=
        Calculator::NormProbFactor(normalizedProb, pTW, cYB);
    }
    // Update the unknown probabilities that we want to find. Use them in the
    // next iteration.
    (*data)[pAGivenX.repr()] = (*data)[cXA.repr()]/( (*data)[cXA.repr()] +
        (*data)[cXB.repr()] );
    (*data)[pBGivenX.repr()] = (*data)[cXB.repr()]/( (*data)[cXB.repr()] +
        (*data)[cXA.repr()] );
    (*data)[pAGivenY.repr()] = (*data)[cYA.repr()]/( (*data)[cYA.repr()] +
        (*data)[cYB.repr()] );
    (*data)[pBGivenY.repr()] = (*data)[cYB.repr()]/( (*data)[cYB.repr()] +
        (*data)[cYA.repr()] );

    // The ultimate value we want to maximize. This should increase with each
    // iteration.
    Calculator::UpdateProbOfObsDataSeq(n, data, tag_sequences);
    saved_obs_seq_probs.push_back((*data)[n.repr()]);
    OutputHelper::PrintDataRow(i + 1, rowOfNots, *data);
  }
}

void OutputResults(map<string, double> &data, Notation n, const vector<string>
                   &tag_sequences) {
  cout << "\n--Results based on " << NUMBER_ITERATIONS << " iterations--\n";
  ofstream fout("observed_data_probabilities.txt");
  for (int i = 0; i < saved_obs_seq_probs.size(); ++i) {
    fout << saved_obs_seq_probs[i] << endl;
  }
  cout << "Values of " << n << " have been written to "
    "observed_data_probabilities.txt." << endl << endl;

  cout << "Final " << n << ": " << data[n.repr()] << endl;
  cout << "Final " << pAGivenX << ": " << data[pAGivenX.repr()] << endl;
  cout << "Final " << pBGivenX << ": " << data[pBGivenX.repr()] << endl;
  cout << "Final " << pAGivenY << ": " << data[pAGivenY.repr()] << endl;
  cout << "Final " << pBGivenY << ": " << data[pBGivenY.repr()] << endl << endl;

  cout << "Determining the best matching tag sequence:\n";
  vector<string> tags = NotationHelper::Individualize(tag_sequences.at(0));
  Notation pTW_first("P", OBSERVED_DATA, AND_DELIM, tags);
  Notation *best_pTGivenW = NULL;
  string best_match_string_repr = pTW_first.repr();
  for (string seq : tag_sequences) {
    vector<string> tags = NotationHelper::Individualize(seq);
    Notation pTW("P", OBSERVED_DATA, AND_DELIM, tags);
    Notation pTGivenW("P", tags, GIVEN_DELIM, OBSERVED_DATA);
    // Compute P(t|w). Technically not used because divided values seem to
    // incorrectly yield >1 (decimals too small, possibly).
    data[pTGivenW.repr()] = data[pTW.repr()] / data[n.repr()];
    if (DO_SHORT_SEQ) { // Only print for short seq; long seq has too many.
      cout << pTW << ": " << data[pTW.repr()] << endl;
    }
    if (data[pTW.repr()] > data[best_match_string_repr]) {
      best_match_string_repr = pTW.repr();
      delete best_pTGivenW;
      // Same as pTGivenW.
      best_pTGivenW = new Notation("P", tags, GIVEN_DELIM, OBSERVED_DATA);
    }
  }
  string pTAndWRepr = best_match_string_repr;
  cout << "The highest probability found belongs to " << pTAndWRepr << ": " <<
    data[pTAndWRepr] << endl;
  cout << "The best matching tag sequence is " <<
    NotationHelper::Combine(best_pTGivenW->first) << endl;
  delete best_pTGivenW;
}

int main() {
  map<string, double> data;
  PrepareInitialData(&data);
  vector<string> tag_sequences = TagHandler::GenerateTagSequences(TAG_LIST,
      OBSERVED_DATA.size());
  if (DO_SHORT_SEQ) {
    ComputeDataWithBruteForce(&data, pABA, tag_sequences);
    OutputResults(data, pABA, tag_sequences);
  } else {
    ComputeDataWithBruteForce(&data, pLong, tag_sequences);
    OutputResults(data, pLong, tag_sequences);
  }
  return 0;
}
<|endoftext|>