<commit_before>#include <sl.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <push.h>
#include <hardware.h>

#include "rtss.h"

VOID FormatDiskReadWriteRate(
    UINT32 Value,
    WCHAR* Buffer
    );

VOID FormatTime(
    UINT32 Value,
    WCHAR* Buffer
    );

typedef VOID(*OSD_DYNAMIC_FORMAT)(
    UINT32 Value,
    WCHAR* Buffer
    );

OSD_ITEM OsdItems[] = {
    { OSD_GPU_LOAD, 90, L"GPU : %i %%", TRUE},
    { OSD_GPU_TEMP, 75, L"GPU : %i C", TRUE},
    { OSD_GPU_E_CLK, 0, L"GPU : %i MHz", TRUE},
    { OSD_GPU_M_CLK, 0, L"GPU : %i MHz", TRUE},
    { OSD_GPU_VRAM, 90, L"VRAM : %i MB", TRUE},
    { OSD_GPU_FAN,   0, L"GPU : %i RPM", TRUE},
    { OSD_RAM,      90, L"RAM : %i MB", TRUE},
    { OSD_CPU_SPEED, 0, L"CPU : %i MHz", TRUE},
    { OSD_CPU_LOAD, 95, L"CPU : %i %%", TRUE},
    { OSD_CPU_TEMP, 75, L"CPU : %i C", TRUE},
    { OSD_MCU, 0, L"CPUm : %i %%", TRUE},
    { OSD_MTU, 0, L"MTU : %i %%", TRUE},
    { OSD_DISK_RWRATE, 0, NULL, TRUE, NULL, NULL, FormatDiskReadWriteRate },
    { OSD_DISK_RESPONSE, 4000, L"DSK : %i ms", TRUE},
    { OSD_TIME, 0, NULL, TRUE, NULL, NULL, FormatTime },
    { OSD_BUFFERS, 0, L"Buffers : %i", TRUE},
    { OSD_RESOLUTION },
    { OSD_FPS }
};

VOID GetValues( OSD_ITEM* Item )
{
    switch (Item->Flag)
    {
    case OSD_GPU_LOAD:
        Item->Value = hardware.DisplayDevice.Load;
        Item->ValueOverride = NULL;
        break;
    case OSD_GPU_TEMP:
        Item->Value = hardware.DisplayDevice.Temperature;
        Item->ValueOverride = NULL;
        break;
    case OSD_GPU_E_CLK:
        Item->Value = NULL;
        Item->ValueOverride = hardware.DisplayDevice.EngineClock;
        break;
    case OSD_GPU_M_CLK:
        Item->Value = NULL;
        Item->ValueOverride = hardware.DisplayDevice.MemoryClock;
        break;
    case OSD_GPU_VRAM:
        Item->Value = hardware.DisplayDevice.FrameBuffer.Load;
        Item->ValueOverride = hardware.DisplayDevice.FrameBuffer.Used;
        break;
    case OSD_GPU_FAN:
        Item->Value = hardware.DisplayDevice.FanSpeed;
        Item->ValueOverride = NULL;
        break;
    case OSD_RAM:
        Item->Value = hardware.Memory.Load;
        Item->ValueOverride = hardware.Memory.Used;
        break;
    case OSD_CPU_SPEED:
        Item->Value = hardware.Processor.Speed;
        Item->ValueOverride = NULL;
        break;
    case OSD_CPU_LOAD:
        Item->Value = hardware.Processor.Load;
        Item->ValueOverride = NULL;
        break;
    case OSD_CPU_TEMP:
        Item->Value = hardware.Processor.Temperature;
        Item->ValueOverride = NULL;
        break;
    case OSD_MCU:
        Item->Value = hardware.Processor.MaxCoreUsage;
        Item->ValueOverride = NULL;
        break;
    case OSD_MTU:
        Item->Value = hardware.Processor.MaxThreadUsage;
        Item->ValueOverride = NULL;
        break;
    case OSD_DISK_RWRATE:
        Item->Value = NULL;
        Item->ValueOverride = hardware.Disk.ReadWriteRate;
        break;
    case OSD_DISK_RESPONSE:
        //Item->Value = hardware.Disk.ResponseTime;
        Item->ValueOverride = NULL;
        break;
    case OSD_TIME:
        Item->Value = NULL;
        Item->ValueOverride = NULL;
        break;
    case OSD_BUFFERS:
        Item->Value = PushSharedMemory->FrameBufferCount;
        Item->ValueOverride = NULL;
        break;
    case OSD_FPS:
        Item->Value = NULL;
        Item->ValueOverride = NULL;
        break;
    }
}

VOID FormatTime( UINT32 Value, WCHAR* Buffer )
{
    Push_FormatTime(Buffer);
}

VOID FormatDiskReadWriteRate(
    UINT32 Value,
    WCHAR* Buffer
    )
{
    UINT32 rate;
    WCHAR *format;

    rate = Value;

    format = L"DSK : %i B/s";

    if (rate > 1024)
    {
        rate /= 1024;//kB/s
        format = L"DSK : %i kB/s";
    }
    if (rate > 1024)
    {
        rate /= 1024;//MB/s
        format = L"DSK : %i MB/s";
    }

    swprintf(
        Buffer,
        20,
        format,
        rate
        );
}

/**
* Refreshes all on-screen display items.
*/

VOID OSD_Refresh()
{
    UINT8 items = sizeof(OsdItems) / sizeof(OsdItems[0]);
    UINT8 i;

    PushSharedMemory->NumberOfOsdItems = items;

    // Loop and draw all on screen display items
    for (i = 0; i < items; i++)
    {
        GetValues(&OsdItems[i]);

        if (!OsdItems[i].Flag //draw if no flag, could be somebody just wants to display stuff on-screen
            || PushSharedMemory->OSDFlags & OsdItems[i].Flag //if it has a flag, is it set?
            || (OsdItems[i].Threshold && OsdItems[i].Value > OsdItems[i].Threshold)) //is the item's value > it's threshold?
        {
            OsdItems[i].Color = 0xFFFFFF00;

            PushSharedMemory->OSDFlags |= OsdItems[i].Flag;

            // Check what type of formating user wants
            if (OsdItems[i].DynamicFormat)
            {
                OsdItems[i].DynamicFormat(OsdItems[i].ValueOverride ? OsdItems[i].ValueOverride : 0, OsdItems[i].Text);
            }
            else if(OsdItems[i].Format)
            {
                swprintf(
                    OsdItems[i].Text,
                    20,
                    OsdItems[i].DisplayFormat,
                    OsdItems[i].ValueOverride ? OsdItems[i].ValueOverride : OsdItems[i].Value
                    );
            }

            wcscat(OsdItems[i].Text, L"\n");

            if (PushSharedMemory->Overloads & OsdItems[i].Flag)
                OsdItems[i].Color = 0xFFFF0000;
        }
    }

    if (PushOverlayInterface == OVERLAY_INTERFACE_PURE)
        memcpy(PushSharedMemory->OsdItems, OsdItems, sizeof(OsdItems));
    else if (PushOverlayInterface == OVERLAY_INTERFACE_RTSS)
        RTSS_Update(OsdItems);
}<commit_msg>fixed crash when local formatting doesn't happen<commit_after>#include <sl.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <push.h>
#include <hardware.h>

#include "rtss.h"

VOID FormatDiskReadWriteRate(
    UINT32 Value,
    WCHAR* Buffer
    );

VOID FormatTime(
    UINT32 Value,
    WCHAR* Buffer
    );

typedef VOID(*OSD_DYNAMIC_FORMAT)(
    UINT32 Value,
    WCHAR* Buffer
    );

OSD_ITEM OsdItems[] = {
    { OSD_GPU_LOAD, 90, L"GPU : %i %%", TRUE},
    { OSD_GPU_TEMP, 75, L"GPU : %i C", TRUE},
    { OSD_GPU_E_CLK, 0, L"GPU : %i MHz", TRUE},
    { OSD_GPU_M_CLK, 0, L"GPU : %i MHz", TRUE},
    { OSD_GPU_VRAM, 90, L"VRAM : %i MB", TRUE},
    { OSD_GPU_FAN,   0, L"GPU : %i RPM", TRUE},
    { OSD_RAM,      90, L"RAM : %i MB", TRUE},
    { OSD_CPU_SPEED, 0, L"CPU : %i MHz", TRUE},
    { OSD_CPU_LOAD, 95, L"CPU : %i %%", TRUE},
    { OSD_CPU_TEMP, 75, L"CPU : %i C", TRUE},
    { OSD_MCU, 0, L"CPUm : %i %%", TRUE},
    { OSD_MTU, 0, L"MTU : %i %%", TRUE},
    { OSD_DISK_RWRATE, 0, NULL, TRUE, NULL, NULL, FormatDiskReadWriteRate },
    { OSD_DISK_RESPONSE, 4000, L"DSK : %i ms", TRUE},
    { OSD_TIME, 0, NULL, TRUE, NULL, NULL, FormatTime },
    { OSD_BUFFERS, 0, L"Buffers : %i", TRUE},
    { OSD_RESOLUTION },
    { OSD_FPS }
};

VOID GetValues( OSD_ITEM* Item )
{
    switch (Item->Flag)
    {
    case OSD_GPU_LOAD:
        Item->Value = hardware.DisplayDevice.Load;
        Item->ValueOverride = NULL;
        break;
    case OSD_GPU_TEMP:
        Item->Value = hardware.DisplayDevice.Temperature;
        Item->ValueOverride = NULL;
        break;
    case OSD_GPU_E_CLK:
        Item->Value = NULL;
        Item->ValueOverride = hardware.DisplayDevice.EngineClock;
        break;
    case OSD_GPU_M_CLK:
        Item->Value = NULL;
        Item->ValueOverride = hardware.DisplayDevice.MemoryClock;
        break;
    case OSD_GPU_VRAM:
        Item->Value = hardware.DisplayDevice.FrameBuffer.Load;
        Item->ValueOverride = hardware.DisplayDevice.FrameBuffer.Used;
        break;
    case OSD_GPU_FAN:
        Item->Value = hardware.DisplayDevice.FanSpeed;
        Item->ValueOverride = NULL;
        break;
    case OSD_RAM:
        Item->Value = hardware.Memory.Load;
        Item->ValueOverride = hardware.Memory.Used;
        break;
    case OSD_CPU_SPEED:
        Item->Value = hardware.Processor.Speed;
        Item->ValueOverride = NULL;
        break;
    case OSD_CPU_LOAD:
        Item->Value = hardware.Processor.Load;
        Item->ValueOverride = NULL;
        break;
    case OSD_CPU_TEMP:
        Item->Value = hardware.Processor.Temperature;
        Item->ValueOverride = NULL;
        break;
    case OSD_MCU:
        Item->Value = hardware.Processor.MaxCoreUsage;
        Item->ValueOverride = NULL;
        break;
    case OSD_MTU:
        Item->Value = hardware.Processor.MaxThreadUsage;
        Item->ValueOverride = NULL;
        break;
    case OSD_DISK_RWRATE:
        Item->Value = NULL;
        Item->ValueOverride = hardware.Disk.ReadWriteRate;
        break;
    case OSD_DISK_RESPONSE:
        //Item->Value = hardware.Disk.ResponseTime;
        Item->ValueOverride = NULL;
        break;
    case OSD_TIME:
        Item->Value = NULL;
        Item->ValueOverride = NULL;
        break;
    case OSD_BUFFERS:
        Item->Value = PushSharedMemory->FrameBufferCount;
        Item->ValueOverride = NULL;
        break;
    case OSD_FPS:
        Item->Value = NULL;
        Item->ValueOverride = NULL;
        break;
    }
}

VOID FormatTime( UINT32 Value, WCHAR* Buffer )
{
    Push_FormatTime(Buffer);
}

VOID FormatDiskReadWriteRate(
    UINT32 Value,
    WCHAR* Buffer
    )
{
    UINT32 rate;
    WCHAR *format;

    rate = Value;

    format = L"DSK : %i B/s";

    if (rate > 1024)
    {
        rate /= 1024;//kB/s
        format = L"DSK : %i kB/s";
    }
    if (rate > 1024)
    {
        rate /= 1024;//MB/s
        format = L"DSK : %i MB/s";
    }

    swprintf(
        Buffer,
        20,
        format,
        rate
        );
}

/**
* Refreshes all on-screen display items.
*/

VOID OSD_Refresh()
{
    UINT8 items = sizeof(OsdItems) / sizeof(OsdItems[0]);
    UINT8 i;

    PushSharedMemory->NumberOfOsdItems = items;

    // Loop and draw all on screen display items
    for (i = 0; i < items; i++)
    {
        GetValues(&OsdItems[i]);

        if (!OsdItems[i].Flag //draw if no flag, could be somebody just wants to display stuff on-screen
            || PushSharedMemory->OSDFlags & OsdItems[i].Flag //if it has a flag, is it set?
            || (OsdItems[i].Threshold && OsdItems[i].Value > OsdItems[i].Threshold)) //is the item's value > it's threshold?
        {
            OsdItems[i].Color = 0xFFFFFF00;

            PushSharedMemory->OSDFlags |= OsdItems[i].Flag;

            if (OsdItems[i].Format || OsdItems[i].DynamicFormat)
            {
                if (OsdItems[i].DynamicFormat)
                {
                    OsdItems[i].DynamicFormat(OsdItems[i].ValueOverride ? OsdItems[i].ValueOverride : 0, OsdItems[i].Text);
                }
                else if (OsdItems[i].Format)
                {
                    swprintf(
                        OsdItems[i].Text,
                        20,
                        OsdItems[i].DisplayFormat,
                        OsdItems[i].ValueOverride ? OsdItems[i].ValueOverride : OsdItems[i].Value
                        );
                }

                wcscat(OsdItems[i].Text, L"\n");
            }

            if (PushSharedMemory->Overloads & OsdItems[i].Flag)
            {
                OsdItems[i].Color = 0xFFFF0000;
            }
        }
    }

    if (PushOverlayInterface == OVERLAY_INTERFACE_PURE)
        memcpy(PushSharedMemory->OsdItems, OsdItems, sizeof(OsdItems));
    else if (PushOverlayInterface == OVERLAY_INTERFACE_RTSS)
        RTSS_Update(OsdItems);
}<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DBN_CONTRASTIVE_DIVERGENCE_HPP
#define DBN_CONTRASTIVE_DIVERGENCE_HPP

#include "assert.hpp"
#include "batch.hpp"

namespace dbn {

template<std::size_t K, typename RBM>
struct cd_trainer {
    static_assert(K > 0, "CD-0 is not a valid training method");

    typedef RBM rbm_t;

    static constexpr const auto num_hidden = rbm_t::num_hidden;
    static constexpr const auto num_visible = rbm_t::num_visible;

    static constexpr const std::size_t num_visible_mom = rbm_t::Momentum ? num_visible : 0;
    static constexpr const std::size_t num_hidden_mom = rbm_t::Momentum ? num_hidden : 0;

    typedef typename rbm_t::weight weight;

    //Gradients
    fast_matrix<weight, num_visible, num_hidden> w_grad;
    fast_vector<weight, num_visible> vbias_grad;
    fast_vector<weight, num_hidden> hbias_grad;

    //Weights and biases for momentum
    fast_matrix<weight, num_visible_mom, num_hidden_mom> w_inc;
    fast_vector<weight, num_visible_mom> a_inc;
    fast_vector<weight, num_hidden_mom> b_inc;

    template<bool M = rbm_t::Momentum, typename std::enable_if<(!M), bool>::type = false>
    cd_trainer(){
        static_assert(!rbm_t::Momentum, "This constructor should only be used without momentum support");
    }

    template<bool M = rbm_t::Momentum, typename std::enable_if<(M), bool>::type = false>
    cd_trainer() : w_inc(0.0), a_inc(0.0), b_inc(0.0) {
        static_assert(rbm_t::Momentum, "This constructor should only be used with momentum support");
    }

    template<typename T>
    double train_batch(const dbn::batch<T>& batch, RBM& rbm){
        dbn_assert(batch.size() <= static_cast<typename dbn::batch<T>::size_type>(BatchSize), "Invalid size");
        dbn_assert(batch[0].size() == num_visible, "The size of the training sample must match visible units");

        //Size of a minibatch
        auto n_samples = static_cast<weight>(batch.size());

        //Clear the gradients
        vbias_grad = 0.0;
        hbias_grad = 0.0;
        w_grad = 0.0;

        rbm.v1 = 0.0;
        rbm.h1_a = 0.0;
        rbm.h1_s = 0.0;
        rbm.h2_a = 0.0;
        rbm.h2_s = 0.0;
        rbm.v2_a = 0.0;
        rbm.v2_s = 0.0;

        for(auto& items : batch){
            rbm.v1 = items;

            //First step
            rbm.activate_hidden(rbm.h1_a, rbm.h1_s, rbm.v1, rbm.v1);

            //CD-1
            rbm.activate_visible(rbm.h1_a, rbm.h1_s, rbm.v2_a, rbm.v2_s);
            rbm.activate_hidden(rbm.h2_a, rbm.h2_s, rbm.v2_a, rbm.v2_s);

            //CD-k
            for(std::size_t k = 1; k < K; ++k){
                rbm.activate_visible(rbm.h2_a, rbm.h2_s, rbm.v2_a, rbm.v2_s);
                rbm.activate_hidden(rbm.h2_a, rbm.h2_s, rbm.v2_a, rbm.v2_s);
            }

            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w_grad(i, j) += rbm.h1_a(j) * rbm.v1(i) - rbm.h2_a(j) * rbm.v2_a(i);
                }
            }

            vbias_grad += rbm.v1 - rbm.v2_a;
            hbias_grad += rbm.h1_a - rbm.h2_a;
        }

        //Keep only the mean of the gradients
        w_grad /= n_samples;
        vbias_grad /= n_samples;
        hbias_grad /= n_samples;

        nan_check_3(w_grad, vbias_grad, hbias_grad);

        //Update weights
        if(rbm_t::Momentum){
            if(rbm_t::Decay){
                w_inc = w_inc * rbm.momentum + (w_grad - (rbm.w * rbm.weight_cost)) * rbm.learning_rate;
            } else {
                w_inc = w_inc * rbm.momentum + w_grad * rbm.learning_rate;
            }

            rbm.w += w_inc;
        } else {
            if(rbm_t::Decay){
                rbm.w += (w_grad - (rbm.w * rbm.weight_cost)) * rbm.learning_rate;
            } else {
                rbm.w += w_grad * rbm.learning_rate;
            }
        }

        //Update visible biases
        if(rbm_t::Momentum){
            a_inc = a_inc * rbm.momentum + vbias_grad * rbm.learning_rate;
            rbm.a += a_inc;
        } else {
            rbm.a += vbias_grad * rbm.learning_rate;
        }

        //Update hidden biases
        if(rbm_t::Momentum){
            b_inc = b_inc * rbm.momentum + hbias_grad * rbm.learning_rate;
            rbm.b += b_inc;
        } else {
            rbm.b += hbias_grad * rbm.learning_rate;
        }

        //Check for NaN
        nan_check_3(rbm.w, rbm.a, rbm.b);

        //Compute the reconstruction error

        weight error = 0.0;
        for(size_t i = 0; i < num_visible; ++i){
            error += vbias_grad(i) * vbias_grad(i);
        }
        error = sqrt(error / num_visible);

        return error;
    }
};

} //end of dbn namespace

#endif<commit_msg>Remove unecessary code<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DBN_CONTRASTIVE_DIVERGENCE_HPP
#define DBN_CONTRASTIVE_DIVERGENCE_HPP

#include "assert.hpp"
#include "batch.hpp"

namespace dbn {

template<std::size_t K, typename RBM>
struct cd_trainer {
    static_assert(K > 0, "CD-0 is not a valid training method");

    typedef RBM rbm_t;

    static constexpr const auto num_hidden = rbm_t::num_hidden;
    static constexpr const auto num_visible = rbm_t::num_visible;

    static constexpr const std::size_t num_visible_mom = rbm_t::Momentum ? num_visible : 0;
    static constexpr const std::size_t num_hidden_mom = rbm_t::Momentum ? num_hidden : 0;

    typedef typename rbm_t::weight weight;

    //Gradients
    fast_matrix<weight, num_visible, num_hidden> w_grad;
    fast_vector<weight, num_visible> vbias_grad;
    fast_vector<weight, num_hidden> hbias_grad;

    //Weights and biases for momentum
    fast_matrix<weight, num_visible_mom, num_hidden_mom> w_inc;
    fast_vector<weight, num_visible_mom> a_inc;
    fast_vector<weight, num_hidden_mom> b_inc;

    template<bool M = rbm_t::Momentum, typename std::enable_if<(!M), bool>::type = false>
    cd_trainer(){
        static_assert(!rbm_t::Momentum, "This constructor should only be used without momentum support");
    }

    template<bool M = rbm_t::Momentum, typename std::enable_if<(M), bool>::type = false>
    cd_trainer() : w_inc(0.0), a_inc(0.0), b_inc(0.0) {
        static_assert(rbm_t::Momentum, "This constructor should only be used with momentum support");
    }

    template<typename T>
    double train_batch(const dbn::batch<T>& batch, RBM& rbm){
        dbn_assert(batch.size() <= static_cast<typename dbn::batch<T>::size_type>(BatchSize), "Invalid size");
        dbn_assert(batch[0].size() == num_visible, "The size of the training sample must match visible units");

        //Size of a minibatch
        auto n_samples = static_cast<weight>(batch.size());

        //Clear the gradients
        vbias_grad = 0.0;
        hbias_grad = 0.0;
        w_grad = 0.0;

        for(auto& items : batch){
            rbm.v1 = items;

            //First step
            rbm.activate_hidden(rbm.h1_a, rbm.h1_s, rbm.v1, rbm.v1);

            //CD-1
            rbm.activate_visible(rbm.h1_a, rbm.h1_s, rbm.v2_a, rbm.v2_s);
            rbm.activate_hidden(rbm.h2_a, rbm.h2_s, rbm.v2_a, rbm.v2_s);

            //CD-k
            for(std::size_t k = 1; k < K; ++k){
                rbm.activate_visible(rbm.h2_a, rbm.h2_s, rbm.v2_a, rbm.v2_s);
                rbm.activate_hidden(rbm.h2_a, rbm.h2_s, rbm.v2_a, rbm.v2_s);
            }

            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w_grad(i, j) += rbm.h1_a(j) * rbm.v1(i) - rbm.h2_a(j) * rbm.v2_a(i);
                }
            }

            vbias_grad += rbm.v1 - rbm.v2_a;
            hbias_grad += rbm.h1_a - rbm.h2_a;
        }

        //Keep only the mean of the gradients
        w_grad /= n_samples;
        vbias_grad /= n_samples;
        hbias_grad /= n_samples;

        nan_check_3(w_grad, vbias_grad, hbias_grad);

        //Update weights
        if(rbm_t::Momentum){
            if(rbm_t::Decay){
                w_inc = w_inc * rbm.momentum + (w_grad - (rbm.w * rbm.weight_cost)) * rbm.learning_rate;
            } else {
                w_inc = w_inc * rbm.momentum + w_grad * rbm.learning_rate;
            }

            rbm.w += w_inc;
        } else {
            if(rbm_t::Decay){
                rbm.w += (w_grad - (rbm.w * rbm.weight_cost)) * rbm.learning_rate;
            } else {
                rbm.w += w_grad * rbm.learning_rate;
            }
        }

        //Update visible biases
        if(rbm_t::Momentum){
            a_inc = a_inc * rbm.momentum + vbias_grad * rbm.learning_rate;
            rbm.a += a_inc;
        } else {
            rbm.a += vbias_grad * rbm.learning_rate;
        }

        //Update hidden biases
        if(rbm_t::Momentum){
            b_inc = b_inc * rbm.momentum + hbias_grad * rbm.learning_rate;
            rbm.b += b_inc;
        } else {
            rbm.b += hbias_grad * rbm.learning_rate;
        }

        //Check for NaN
        nan_check_3(rbm.w, rbm.a, rbm.b);

        //Compute the reconstruction error

        weight error = 0.0;
        for(size_t i = 0; i < num_visible; ++i){
            error += vbias_grad(i) * vbias_grad(i);
        }
        error = sqrt(error / num_visible);

        return error;
    }
};

} //end of dbn namespace

#endif<|endoftext|>


<commit_before>//
// Created by david on 2019-03-09.
//

#include <tools/nmspc_tools.h>
#include <state/class_state_finite.h>
#include <state/class_state_infinite.h>
#include <model/class_model_factory.h>
#include <simulation/class_simulation_status.h>
#include <simulation/nmspc_settings.h>
#include <general/nmspc_tensor_extra.h>
#include <general/nmspc_quantum_mechanics.h>
#include <stdexcept>
#include <h5pp/h5pp.h>

using Scalar    = std::complex<double>;

bool tools::finite::io::internals::make_extendable_dataset(const std::string & prefix_path) {
    std::string log_string = "/log";  // A logged dataset is not supposed to be extended, just written once.
    return prefix_path.find(log_string) == std::string::npos;
}

void tools::finite::io::write_all_state(const class_state_finite &state, h5pp::File & h5ppFile, const std::string & prefix_path) {
    tools::common::profile::t_hdf.tic();
    switch(settings::output::storage_level){
        case StorageLevel::NONE:
            break;
        case StorageLevel::LIGHT:
            write_bond_matrix(state,h5ppFile,prefix_path);
            break;
        case StorageLevel::NORMAL:
            write_bond_matrices(state,h5ppFile,prefix_path);
            break;
        case StorageLevel::FULL:
            write_full_mps(state,h5ppFile,prefix_path);
            write_full_mpo(state,h5ppFile,prefix_path);
            break;
    }
    h5ppFile.writeDataset(state.get_position()       ,prefix_path + "/state/position");
    h5ppFile.writeDataset(state.get_length()         ,prefix_path + "/state/sites");
    h5ppFile.writeDataset(settings::model::model_type,prefix_path + "/model/model_type");
    tools::common::profile::t_hdf.toc();

}

void tools::finite::io::write_bond_matrices(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path)
/*! Writes down all the "Lambda" bond matrices (singular value matrices), so we can obtain the entanglement spectrum easily.
 */
{
    bool extendable = internals::make_extendable_dataset(prefix_path);
    auto middle = (size_t) (state.get_length() / 2);
    for (size_t i = 0; i < state.get_length(); i++){
        h5ppFile.writeDataset(state.get_MPS(i).get_L(),prefix_path + "/state/mps/L_" + std::to_string(i),extendable);
        if (i == middle){
            h5ppFile.writeDataset(state.midchain_bond(), prefix_path + "/state/mps/L_C", extendable);
        }
    }
    h5ppFile.writeDataset(state.get_truncation_error(), prefix_path + "/state/truncation_error",extendable);
}

void tools::finite::io::write_bond_matrix(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path)
/*! Writes down all the "Lambda" bond matrices (singular value matrices), so we can obtain the entanglement spectrum easily.
 */
{
    bool extendable = internals::make_extendable_dataset(prefix_path);
    auto middle = (size_t) (state.get_length() / 2);
    h5ppFile.writeDataset(state.get_MPS(middle).get_LC(),prefix_path + "/state/mps/L_C",extendable);
    h5ppFile.writeDataset(state.get_truncation_error(middle), prefix_path + "/state/truncation_error",extendable);
}

void tools::finite::io::write_full_mps(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path)
/*!
 * Writes down the full MPS in "L-G-L-G- LC -G-L-G-L" notation.
 *
 */
{
    bool extendable = internals::make_extendable_dataset(prefix_path);
    write_bond_matrices(state,h5ppFile,prefix_path);
    for (size_t i = 0; i < state.get_length(); i++){
        h5ppFile.writeDataset(state.get_MPS(i).get_M() ,prefix_path + "/state/mps/M_" + std::to_string(i),extendable);
    }
}

void tools::finite::io::write_full_mpo(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path) {
    // Write all the MPO's
    // Remember to write tensors in row-major state order because that's what output uses.
    bool extendable = internals::make_extendable_dataset(prefix_path);
    for (auto site = 0ul; site < state.get_length(); site++){
        h5ppFile.writeDataset(state.get_MPO(site).MPO(), prefix_path + "/state/mpo/H_" + std::to_string(site),extendable);
        //Write MPO properties as attributes
        auto values = state.get_MPO(site).get_parameter_values();
        auto names  = state.get_MPO(site).get_parameter_names();
        for (size_t i = 0; i < std::min(values.size(), names.size()); i++){
            h5ppFile.writeAttributeToLink(values[i], names[i],prefix_path + "/state/mpo/H_" + std::to_string(site));
        }
    }
}

void tools::finite::io::write_model(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path){
    // Write down the Hamiltonian metadata as a table
    // Remember to write tensors in row-major state order because that's what output uses.
    if(settings::output::storage_level == StorageLevel::NONE) return;
    Eigen::MatrixXd hamiltonian_props;
    for (auto site = 0ul ; site < state.get_length(); site++){
        auto props = state.get_MPO(site).get_parameter_values();
        Eigen::ArrayXd  temp_row  = Eigen::Map<Eigen::ArrayXd> (props.data(),props.size());
        hamiltonian_props.conservativeResize(hamiltonian_props.rows()+1, temp_row.size());
        hamiltonian_props.bottomRows(1) = temp_row.transpose();
    }
    bool extendable = internals::make_extendable_dataset(prefix_path);
    h5ppFile.writeDataset(hamiltonian_props,prefix_path + "/model/Hamiltonian",extendable);
    int col = 0;
    for (auto &name : state.MPO_L.front()->get_parameter_names()){
        std::string attr_value = name;
        std::string attr_name  = "FIELD_" + std::to_string(col) + "_NAME";
        h5ppFile.writeAttributeToLink(attr_value, attr_name,prefix_path + "/model/Hamiltonian");
        col++;
    }
}

void tools::finite::io::write_all_measurements(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path){
    state.do_all_measurements();
    tools::log->trace("Writing all measurements...")
    tools::common::profile::t_hdf.tic();
    h5ppFile.writeDataset(state.measurements.length.value()                        , prefix_path + "/measurements/length");
    h5ppFile.writeDataset(state.measurements.norm.value()                          , prefix_path + "/measurements/norm");
    h5ppFile.writeDataset(state.measurements.bond_dimensions.value()               , prefix_path + "/measurements/bond_dimensions");
    h5ppFile.writeDataset(state.measurements.bond_dimension_midchain.value()       , prefix_path + "/measurements/bond_dimension_midchain");
    h5ppFile.writeDataset(state.measurements.energy.value()                        , prefix_path + "/measurements/energy");
    h5ppFile.writeDataset(state.measurements.energy_per_site.value()               , prefix_path + "/measurements/energy_per_site");
    h5ppFile.writeDataset(state.measurements.energy_variance_mpo.value()           , prefix_path + "/measurements/energy_variance_mpo");
    h5ppFile.writeDataset(state.measurements.energy_variance_per_site.value()      , prefix_path + "/measurements/energy_variance_per_site");
    h5ppFile.writeDataset(state.measurements.entanglement_entropies.value()        , prefix_path + "/measurements/entanglement_entropies");
    h5ppFile.writeDataset(state.measurements.entanglement_entropy_midchain.value() , prefix_path + "/measurements/entanglement_entropy_midchain");
    h5ppFile.writeDataset(state.measurements.spin_components.value()               , prefix_path + "/measurements/spin_components");
    h5ppFile.writeDataset(state.measurements.spin_component_sx.value()             , prefix_path + "/measurements/spin_component_sx");
    h5ppFile.writeDataset(state.measurements.spin_component_sy.value()             , prefix_path + "/measurements/spin_component_sy");
    h5ppFile.writeDataset(state.measurements.spin_component_sz.value()             , prefix_path + "/measurements/spin_component_sz");
    tools::common::profile::t_hdf.toc();
    tools::log->trace("Writing all measurements... OK")

}

void tools::finite::io::write_projection_to_closest_parity_sector(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path, std::string parity_sector){
    if (parity_sector == "none") return;
    auto state_projected = tools::finite::ops::get_projection_to_closest_parity_sector(state, parity_sector);
    state_projected.unset_measurements();
    state_projected.do_all_measurements();
    tools::log->trace("Variance of projected state: {:.8f}", std::log10(tools::finite::measure::energy_variance_per_site(state_projected)));
    tools::finite::io::write_all_state(state_projected,h5ppFile, prefix_path + "/projections/" + parity_sector);
    tools::finite::io::write_all_measurements(state_projected,h5ppFile, prefix_path + "/projections/" + parity_sector);
}

void tools::finite::io::load_from_hdf5(const h5pp::File & h5ppFile, class_state_finite & state, class_simulation_status &sim_status, const std::string & prefix_path){
    // Load into state
    try{
        sim_status = tools::common::io::load_sim_status_from_hdf5(h5ppFile,prefix_path);
        state     = load_state_from_hdf5(h5ppFile,prefix_path);
        state.set_sweeps(sim_status.iteration);
        tools::finite::debug::check_integrity(state);
    }catch(std::exception &ex){
        throw std::runtime_error("Failed to load from output: " + std::string(ex.what()));
    }
}

class_state_finite tools::finite::io::load_state_from_hdf5(const h5pp::File & h5ppFile, const std::string & prefix_path){
    class_state_finite state;
    size_t position = 0;
    size_t sites   = 0;
    Eigen::Tensor<Scalar,3> G;
    Eigen::Tensor<Scalar,1> L;
    Eigen::Tensor<Scalar,4> H;
    Eigen::MatrixXd Hamiltonian_params;
    std::string model_type;
    try{
        h5ppFile.readDataset(position             , prefix_path + "/state/position");
        h5ppFile.readDataset(sites                , prefix_path + "/state/sites");
        h5ppFile.readDataset(Hamiltonian_params   , prefix_path + "/model/Hamiltonian");
        h5ppFile.readDataset(model_type           , prefix_path + "/model/model_type");
    }catch (std::exception &ex){
        throw std::runtime_error("Couldn't read necessary model parameters: " + std::string(ex.what()));
    }

    try {
        for(size_t i = 0; i < sites; i++){
            h5ppFile.readDataset(G, prefix_path + "/state/mps/G_" + std::to_string(i));
            h5ppFile.readDataset(L, prefix_path + "/state/mps/L_" + std::to_string(i));
            h5ppFile.readDataset(H, prefix_path + "/state/mpo/H_" + std::to_string(i));
            if(i <= (size_t)position ) {
                if(not state.MPS_L.empty() and state.MPS_L.back().get_chiR() != G.dimension(1)){
                    throw std::runtime_error("Mismatch in adjacent MPS dimensions");
                }
                state.MPS_L.emplace_back(G,L,i);
                state.MPO_L.emplace_back(class_model_factory::create_mpo(i,model_type,Hamiltonian_params.row(i)));
            }
            else{
                if(not state.MPS_R.empty() and state.MPS_R.back().get_chiR() != G.dimension(1)){
                    throw std::runtime_error("Mismatch in adjacent MPS dimensions");
                }
                state.MPS_R.emplace_back(G,L,i);
                state.MPO_R.emplace_back(class_model_factory::create_mpo(i,model_type,Hamiltonian_params.row(i)));
            }
        }
        h5ppFile.readDataset(state.midchain_bond()    , prefix_path + "/state/mps/L_C");
        if (state.MPS_L.size() + state.MPS_R.size() != (size_t)sites){
            throw std::runtime_error("Number of sites loaded does not match the number of sites advertised by the output file");
        }
        if (position != state.get_position()){
            throw std::runtime_error("Position loaded does not match the position read from the output file");
        }

    }catch (std::exception &ex){
        throw std::runtime_error("Could not read MPS/MPO tensors from file: " + std::string(ex.what()));
    }
    tools::finite::mps::rebuild_environments(state);
    return state;
}
<commit_msg>Projecting also when stuck<commit_after>//
// Created by david on 2019-03-09.
//

#include <tools/nmspc_tools.h>
#include <state/class_state_finite.h>
#include <state/class_state_infinite.h>
#include <model/class_model_factory.h>
#include <simulation/class_simulation_status.h>
#include <simulation/nmspc_settings.h>
#include <general/nmspc_tensor_extra.h>
#include <general/nmspc_quantum_mechanics.h>
#include <stdexcept>
#include <h5pp/h5pp.h>

using Scalar    = std::complex<double>;

bool tools::finite::io::internals::make_extendable_dataset(const std::string & prefix_path) {
    std::string log_string = "/log";  // A logged dataset is not supposed to be extended, just written once.
    return prefix_path.find(log_string) == std::string::npos;
}

void tools::finite::io::write_all_state(const class_state_finite &state, h5pp::File & h5ppFile, const std::string & prefix_path) {
    tools::common::profile::t_hdf.tic();
    switch(settings::output::storage_level){
        case StorageLevel::NONE:
            break;
        case StorageLevel::LIGHT:
            write_bond_matrix(state,h5ppFile,prefix_path);
            break;
        case StorageLevel::NORMAL:
            write_bond_matrices(state,h5ppFile,prefix_path);
            break;
        case StorageLevel::FULL:
            write_full_mps(state,h5ppFile,prefix_path);
            write_full_mpo(state,h5ppFile,prefix_path);
            break;
    }
    h5ppFile.writeDataset(state.get_position()       ,prefix_path + "/state/position");
    h5ppFile.writeDataset(state.get_length()         ,prefix_path + "/state/sites");
    h5ppFile.writeDataset(settings::model::model_type,prefix_path + "/model/model_type");
    tools::common::profile::t_hdf.toc();

}

void tools::finite::io::write_bond_matrices(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path)
/*! Writes down all the "Lambda" bond matrices (singular value matrices), so we can obtain the entanglement spectrum easily.
 */
{
    bool extendable = internals::make_extendable_dataset(prefix_path);
    auto middle = (size_t) (state.get_length() / 2);
    for (size_t i = 0; i < state.get_length(); i++){
        h5ppFile.writeDataset(state.get_MPS(i).get_L(),prefix_path + "/state/mps/L_" + std::to_string(i),extendable);
        if (i == middle){
            h5ppFile.writeDataset(state.midchain_bond(), prefix_path + "/state/mps/L_C", extendable);
        }
    }
    h5ppFile.writeDataset(state.get_truncation_error(), prefix_path + "/state/truncation_error",extendable);
}

void tools::finite::io::write_bond_matrix(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path)
/*! Writes down all the "Lambda" bond matrices (singular value matrices), so we can obtain the entanglement spectrum easily.
 */
{
    bool extendable = internals::make_extendable_dataset(prefix_path);
    auto middle = (size_t) (state.get_length() / 2);
    h5ppFile.writeDataset(state.get_MPS(middle).get_LC(),prefix_path + "/state/mps/L_C",extendable);
    h5ppFile.writeDataset(state.get_truncation_error(middle), prefix_path + "/state/truncation_error",extendable);
}

void tools::finite::io::write_full_mps(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path)
/*!
 * Writes down the full MPS in "L-G-L-G- LC -G-L-G-L" notation.
 *
 */
{
    bool extendable = internals::make_extendable_dataset(prefix_path);
    write_bond_matrices(state,h5ppFile,prefix_path);
    for (size_t i = 0; i < state.get_length(); i++){
        h5ppFile.writeDataset(state.get_MPS(i).get_M() ,prefix_path + "/state/mps/M_" + std::to_string(i),extendable);
    }
}

void tools::finite::io::write_full_mpo(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path) {
    // Write all the MPO's
    // Remember to write tensors in row-major state order because that's what output uses.
    bool extendable = internals::make_extendable_dataset(prefix_path);
    for (auto site = 0ul; site < state.get_length(); site++){
        h5ppFile.writeDataset(state.get_MPO(site).MPO(), prefix_path + "/state/mpo/H_" + std::to_string(site),extendable);
        //Write MPO properties as attributes
        auto values = state.get_MPO(site).get_parameter_values();
        auto names  = state.get_MPO(site).get_parameter_names();
        for (size_t i = 0; i < std::min(values.size(), names.size()); i++){
            h5ppFile.writeAttributeToLink(values[i], names[i],prefix_path + "/state/mpo/H_" + std::to_string(site));
        }
    }
}

void tools::finite::io::write_model(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path){
    // Write down the Hamiltonian metadata as a table
    // Remember to write tensors in row-major state order because that's what output uses.
    if(settings::output::storage_level == StorageLevel::NONE) return;
    Eigen::MatrixXd hamiltonian_props;
    for (auto site = 0ul ; site < state.get_length(); site++){
        auto props = state.get_MPO(site).get_parameter_values();
        Eigen::ArrayXd  temp_row  = Eigen::Map<Eigen::ArrayXd> (props.data(),props.size());
        hamiltonian_props.conservativeResize(hamiltonian_props.rows()+1, temp_row.size());
        hamiltonian_props.bottomRows(1) = temp_row.transpose();
    }
    bool extendable = internals::make_extendable_dataset(prefix_path);
    h5ppFile.writeDataset(hamiltonian_props,prefix_path + "/model/Hamiltonian",extendable);
    int col = 0;
    for (auto &name : state.MPO_L.front()->get_parameter_names()){
        std::string attr_value = name;
        std::string attr_name  = "FIELD_" + std::to_string(col) + "_NAME";
        h5ppFile.writeAttributeToLink(attr_value, attr_name,prefix_path + "/model/Hamiltonian");
        col++;
    }
}

void tools::finite::io::write_all_measurements(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path){
    state.do_all_measurements();
    tools::log->trace("Writing all measurements...");
    tools::common::profile::t_hdf.tic();
    h5ppFile.writeDataset(state.measurements.length.value()                        , prefix_path + "/measurements/length");
    h5ppFile.writeDataset(state.measurements.norm.value()                          , prefix_path + "/measurements/norm");
    h5ppFile.writeDataset(state.measurements.bond_dimensions.value()               , prefix_path + "/measurements/bond_dimensions");
    h5ppFile.writeDataset(state.measurements.bond_dimension_midchain.value()       , prefix_path + "/measurements/bond_dimension_midchain");
    h5ppFile.writeDataset(state.measurements.energy.value()                        , prefix_path + "/measurements/energy");
    h5ppFile.writeDataset(state.measurements.energy_per_site.value()               , prefix_path + "/measurements/energy_per_site");
    h5ppFile.writeDataset(state.measurements.energy_variance_mpo.value()           , prefix_path + "/measurements/energy_variance_mpo");
    h5ppFile.writeDataset(state.measurements.energy_variance_per_site.value()      , prefix_path + "/measurements/energy_variance_per_site");
    h5ppFile.writeDataset(state.measurements.entanglement_entropies.value()        , prefix_path + "/measurements/entanglement_entropies");
    h5ppFile.writeDataset(state.measurements.entanglement_entropy_midchain.value() , prefix_path + "/measurements/entanglement_entropy_midchain");
    h5ppFile.writeDataset(state.measurements.spin_components.value()               , prefix_path + "/measurements/spin_components");
    h5ppFile.writeDataset(state.measurements.spin_component_sx.value()             , prefix_path + "/measurements/spin_component_sx");
    h5ppFile.writeDataset(state.measurements.spin_component_sy.value()             , prefix_path + "/measurements/spin_component_sy");
    h5ppFile.writeDataset(state.measurements.spin_component_sz.value()             , prefix_path + "/measurements/spin_component_sz");
    tools::common::profile::t_hdf.toc();
    tools::log->trace("Writing all measurements... OK");

}

void tools::finite::io::write_projection_to_closest_parity_sector(const class_state_finite & state, h5pp::File & h5ppFile, const std::string & prefix_path, std::string parity_sector){
    if (parity_sector == "none") return;
    auto state_projected = tools::finite::ops::get_projection_to_closest_parity_sector(state, parity_sector);
    state_projected.unset_measurements();
    state_projected.do_all_measurements();
    tools::log->trace("Variance of projected state: {:.8f}", std::log10(tools::finite::measure::energy_variance_per_site(state_projected)));
    tools::finite::io::write_all_state(state_projected,h5ppFile, prefix_path + "/projections/" + parity_sector);
    tools::finite::io::write_all_measurements(state_projected,h5ppFile, prefix_path + "/projections/" + parity_sector);
}

void tools::finite::io::load_from_hdf5(const h5pp::File & h5ppFile, class_state_finite & state, class_simulation_status &sim_status, const std::string & prefix_path){
    // Load into state
    try{
        sim_status = tools::common::io::load_sim_status_from_hdf5(h5ppFile,prefix_path);
        state     = load_state_from_hdf5(h5ppFile,prefix_path);
        state.set_sweeps(sim_status.iteration);
        tools::finite::debug::check_integrity(state);
    }catch(std::exception &ex){
        throw std::runtime_error("Failed to load from output: " + std::string(ex.what()));
    }
}

class_state_finite tools::finite::io::load_state_from_hdf5(const h5pp::File & h5ppFile, const std::string & prefix_path){
    class_state_finite state;
    size_t position = 0;
    size_t sites   = 0;
    Eigen::Tensor<Scalar,3> G;
    Eigen::Tensor<Scalar,1> L;
    Eigen::Tensor<Scalar,4> H;
    Eigen::MatrixXd Hamiltonian_params;
    std::string model_type;
    try{
        h5ppFile.readDataset(position             , prefix_path + "/state/position");
        h5ppFile.readDataset(sites                , prefix_path + "/state/sites");
        h5ppFile.readDataset(Hamiltonian_params   , prefix_path + "/model/Hamiltonian");
        h5ppFile.readDataset(model_type           , prefix_path + "/model/model_type");
    }catch (std::exception &ex){
        throw std::runtime_error("Couldn't read necessary model parameters: " + std::string(ex.what()));
    }

    try {
        for(size_t i = 0; i < sites; i++){
            h5ppFile.readDataset(G, prefix_path + "/state/mps/G_" + std::to_string(i));
            h5ppFile.readDataset(L, prefix_path + "/state/mps/L_" + std::to_string(i));
            h5ppFile.readDataset(H, prefix_path + "/state/mpo/H_" + std::to_string(i));
            if(i <= (size_t)position ) {
                if(not state.MPS_L.empty() and state.MPS_L.back().get_chiR() != G.dimension(1)){
                    throw std::runtime_error("Mismatch in adjacent MPS dimensions");
                }
                state.MPS_L.emplace_back(G,L,i);
                state.MPO_L.emplace_back(class_model_factory::create_mpo(i,model_type,Hamiltonian_params.row(i)));
            }
            else{
                if(not state.MPS_R.empty() and state.MPS_R.back().get_chiR() != G.dimension(1)){
                    throw std::runtime_error("Mismatch in adjacent MPS dimensions");
                }
                state.MPS_R.emplace_back(G,L,i);
                state.MPO_R.emplace_back(class_model_factory::create_mpo(i,model_type,Hamiltonian_params.row(i)));
            }
        }
        h5ppFile.readDataset(state.midchain_bond()    , prefix_path + "/state/mps/L_C");
        if (state.MPS_L.size() + state.MPS_R.size() != (size_t)sites){
            throw std::runtime_error("Number of sites loaded does not match the number of sites advertised by the output file");
        }
        if (position != state.get_position()){
            throw std::runtime_error("Position loaded does not match the position read from the output file");
        }

    }catch (std::exception &ex){
        throw std::runtime_error("Could not read MPS/MPO tensors from file: " + std::string(ex.what()));
    }
    tools::finite::mps::rebuild_environments(state);
    return state;
}
<|endoftext|>


<commit_before>#include <Doremi/Core/Include/PlayerSpawnerHandler.hpp>
#include <Doremi/Core/Include/EventHandler/Events/TriggerEvent.hpp>
#include <Doremi/Core/Include/EntityComponent/Components/TransformComponent.hpp>
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/CharacterControlManager.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <Doremi/Core/Include/EntityComponent/EntityHandler.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlayerRespawnEvent.hpp>
#include <Doremi/Core/Include/EventHandler/EventHandler.hpp>
#include <iostream>

namespace Doremi
{
    namespace Core
    {
        PlayerSpawnerHandler* PlayerSpawnerHandler::m_singleton = nullptr;

        PlayerSpawnerHandler* PlayerSpawnerHandler::GetInstance()
        {
            if(m_singleton == nullptr)
            {
                std::cout << "Called GetInstance befor StartupPlayerSpawnerHandler was called" << std::endl;
            }
            return m_singleton;
        }

        void PlayerSpawnerHandler::StartupPlayerSpawnerHandler(const DoremiEngine::Core::SharedContext& p_sharedContext)
        {
            if(m_singleton != nullptr)
            {
                std::runtime_error("StartupPlayerSpawnerHandler was called");
            }
            m_singleton = new PlayerSpawnerHandler(p_sharedContext);
        }

        PlayerSpawnerHandler::PlayerSpawnerHandler(const DoremiEngine::Core::SharedContext& p_sharedContext) : m_sharedContext(p_sharedContext)
        {
            EventHandler::GetInstance()->Subscribe(EventType::Trigger, this);
        }

        PlayerSpawnerHandler::~PlayerSpawnerHandler() {}

        EntityID PlayerSpawnerHandler::GetCurrentSpawnerEntityID() { return m_currentPlayerSpawner; }

        void PlayerSpawnerHandler::SetCurrentSpawner(EntityID p_entityID) { m_currentPlayerSpawner = p_entityID; }

        void PlayerSpawnerHandler::RespawnPlayer(EntityID p_entityID)
        {
            DoremiEngine::Physics::CharacterControlManager& t_characterBodyManager = m_sharedContext.GetPhysicsModule().GetCharacterControlManager();
            DoremiEngine::Physics::RigidBodyManager& t_rigidBodyManager = m_sharedContext.GetPhysicsModule().GetRigidBodyManager();

            // Get position and orientation of the trigger..
            DirectX::XMFLOAT3 t_triggerPosition = t_rigidBodyManager.GetBodyPosition(m_currentPlayerSpawner);
            DirectX::XMFLOAT4 t_triggerOrientation = t_rigidBodyManager.GetBodyOrientation(m_currentPlayerSpawner);

            // ..and set it to the players position, orientation
            t_characterBodyManager.SetPosition(p_entityID, t_triggerPosition);

            // Since we don't know if this will be called befor sync or not, we set it to the transform as well
            TransformComponent* t_transComp = GetComponent<TransformComponent>(p_entityID);
            t_transComp->position = t_triggerPosition;
            t_transComp->rotation = t_triggerOrientation;

            // Create event for other purposes
            PlayerRespawnEvent* t_playerRespawn = new PlayerRespawnEvent(p_entityID, t_triggerPosition, t_triggerOrientation);
            EventHandler::GetInstance()->BroadcastEvent(t_playerRespawn);
        }

        void PlayerSpawnerHandler::OnEvent(Event* p_event)
        {
            if(p_event->eventType == EventType::Trigger)
            {
                TriggerEvent* t_triggEvent = static_cast<TriggerEvent*>(p_event);

                // If spawn point trigger
                if(t_triggEvent->triggerType == TriggerType::NewSpawnPointTrigger)
                {
                    // Could get who got the spawner here as well? If we want player specific spawners
                    m_currentPlayerSpawner = t_triggEvent->triggerEntityID;
                }
            }
        }
    }
}<commit_msg>Commented nonfunctional spawnpoint change<commit_after>#include <Doremi/Core/Include/PlayerSpawnerHandler.hpp>
#include <Doremi/Core/Include/EventHandler/Events/TriggerEvent.hpp>
#include <Doremi/Core/Include/EntityComponent/Components/TransformComponent.hpp>
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/CharacterControlManager.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <Doremi/Core/Include/EntityComponent/EntityHandler.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlayerRespawnEvent.hpp>
#include <Doremi/Core/Include/EventHandler/EventHandler.hpp>
#include <iostream>

namespace Doremi
{
    namespace Core
    {
        PlayerSpawnerHandler* PlayerSpawnerHandler::m_singleton = nullptr;

        PlayerSpawnerHandler* PlayerSpawnerHandler::GetInstance()
        {
            if(m_singleton == nullptr)
            {
                std::cout << "Called GetInstance befor StartupPlayerSpawnerHandler was called" << std::endl;
            }
            return m_singleton;
        }

        void PlayerSpawnerHandler::StartupPlayerSpawnerHandler(const DoremiEngine::Core::SharedContext& p_sharedContext)
        {
            if(m_singleton != nullptr)
            {
                std::runtime_error("StartupPlayerSpawnerHandler was called");
            }
            m_singleton = new PlayerSpawnerHandler(p_sharedContext);
        }

        PlayerSpawnerHandler::PlayerSpawnerHandler(const DoremiEngine::Core::SharedContext& p_sharedContext) : m_sharedContext(p_sharedContext)
        {
            EventHandler::GetInstance()->Subscribe(EventType::Trigger, this);
        }

        PlayerSpawnerHandler::~PlayerSpawnerHandler() {}

        EntityID PlayerSpawnerHandler::GetCurrentSpawnerEntityID() { return m_currentPlayerSpawner; }

        void PlayerSpawnerHandler::SetCurrentSpawner(EntityID p_entityID) { m_currentPlayerSpawner = p_entityID; }

        void PlayerSpawnerHandler::RespawnPlayer(EntityID p_entityID)
        {
            DoremiEngine::Physics::CharacterControlManager& t_characterBodyManager = m_sharedContext.GetPhysicsModule().GetCharacterControlManager();
            DoremiEngine::Physics::RigidBodyManager& t_rigidBodyManager = m_sharedContext.GetPhysicsModule().GetRigidBodyManager();

            // Get position and orientation of the trigger..
            DirectX::XMFLOAT3 t_triggerPosition = t_rigidBodyManager.GetBodyPosition(m_currentPlayerSpawner);
            DirectX::XMFLOAT4 t_triggerOrientation = t_rigidBodyManager.GetBodyOrientation(m_currentPlayerSpawner);

            // ..and set it to the players position, orientation
            t_characterBodyManager.SetPosition(p_entityID, t_triggerPosition);

            // Since we don't know if this will be called befor sync or not, we set it to the transform as well
            TransformComponent* t_transComp = GetComponent<TransformComponent>(p_entityID);
            t_transComp->position = t_triggerPosition;
            t_transComp->rotation = t_triggerOrientation;

            // Create event for other purposes
            PlayerRespawnEvent* t_playerRespawn = new PlayerRespawnEvent(p_entityID, t_triggerPosition, t_triggerOrientation);
            EventHandler::GetInstance()->BroadcastEvent(t_playerRespawn);
        }

        void PlayerSpawnerHandler::OnEvent(Event* p_event)
        {
            // if(p_event->eventType == EventType::Trigger)
            //{
            //    TriggerEvent* t_triggEvent = static_cast<TriggerEvent*>(p_event);

            //    // If spawn point trigger
            //    if(t_triggEvent->triggerType == TriggerType::NewSpawnPointTrigger)
            //    {
            //        // Could get who got the spawner here as well? If we want player specific spawners
            //        m_currentPlayerSpawner = t_triggEvent->triggerEntityID;
            //    }
            //}
        }
    }
}<|endoftext|>


<commit_before>/*
 * Host based encapsulated base sweeper.
 */

#ifndef _PFASST_ENCAPSULATED_HPP_
#define _PFASST_ENCAPSULATED_HPP_

#include <vector>
#include <memory>

#include "../interfaces.hpp"
#include "../quadrature.hpp"

using namespace std;

namespace pfasst
{
  namespace encap
  {

    typedef enum EncapType { solution, function } EncapType;

    /**
     * basic encapsulation.
     *
     * An Encapsulation provides basic functionality of the user data used by PFASST such as
     * mathematical operation @em axpy \\(y=ax+y\\) and packing/unpacking for message passing.
     * @tparam time time precision
     *     defaults to pfasst::time_precision
     */
    template<typename time = time_precision>
    class Encapsulation
    {
      public:
        //! @{
        virtual ~Encapsulation() { }
        //! @}

        //! @{
        // required for time-parallel communications
        virtual void send()
        {
          throw NotImplementedYet("pfasst");
        }
        virtual void recv()
        {
          throw NotImplementedYet("pfasst");
        }
        //! @}

        //! @{
        // required for host based encap helpers
        virtual void zero()
        {
          throw NotImplementedYet("encap");
        }
        virtual void copy(shared_ptr<const Encapsulation<time>>)
        {
          throw NotImplementedYet("encap");
        }
        //! @}

        //! @{
        /**
         * provides basic mathematical operation \\(y+=ax\\).
         *
         * This is the main mathematical operation applied by PFASST on the data structures.
         * Here, \\(a\\) is a time point and \\(x\\) another data structure (usually of the
         * same type).
         */
        virtual void saxpy(time /*a*/, shared_ptr<const Encapsulation<time>> /*x*/)
        {
          throw NotImplementedYet("encap");
        }

        /**
         * defines matrix-vector multiplication for this data type.
         */
        virtual void mat_apply(vector<shared_ptr<Encapsulation<time>>> dst, time a, matrix<time> mat,
			       vector<shared_ptr<Encapsulation<time>>> src, bool zero = true)
        {
          size_t ndst = dst.size();
          size_t nsrc = src.size();

          if (zero) {
	    for (auto elem : dst) { elem->zero(); }
	  }

	  for (size_t n = 0; n < ndst; n++) {
	    for (size_t m = 0; m < nsrc; m++) {
	      auto s = mat(n, m);
	      if (s != 0.0) {
		dst[n]->saxpy(a*s, src[m]);
	      }
            }
          }
        }
        //! @}
    };

    template<typename time = time_precision>
    class EncapFactory
    {
      public:
        virtual shared_ptr<Encapsulation<time>> create(const EncapType) = 0;
    };

  }
}

#endif
<commit_msg>Untabify.<commit_after>/*
 * Host based encapsulated base sweeper.
 */

#ifndef _PFASST_ENCAPSULATED_HPP_
#define _PFASST_ENCAPSULATED_HPP_

#include <vector>
#include <memory>

#include "../interfaces.hpp"
#include "../quadrature.hpp"

using namespace std;

namespace pfasst
{
  namespace encap
  {

    typedef enum EncapType { solution, function } EncapType;

    /**
     * basic encapsulation.
     *
     * An Encapsulation provides basic functionality of the user data used by PFASST such as
     * mathematical operation @em axpy \\(y=ax+y\\) and packing/unpacking for message passing.
     * @tparam time time precision
     *     defaults to pfasst::time_precision
     */
    template<typename time = time_precision>
    class Encapsulation
    {
      public:
        //! @{
        virtual ~Encapsulation() { }
        //! @}

        //! @{
        // required for time-parallel communications
        virtual void send()
        {
          throw NotImplementedYet("pfasst");
        }
        virtual void recv()
        {
          throw NotImplementedYet("pfasst");
        }
        //! @}

        //! @{
        // required for host based encap helpers
        virtual void zero()
        {
          throw NotImplementedYet("encap");
        }
        virtual void copy(shared_ptr<const Encapsulation<time>>)
        {
          throw NotImplementedYet("encap");
        }
        //! @}

        //! @{
        /**
         * provides basic mathematical operation \\(y+=ax\\).
         *
         * This is the main mathematical operation applied by PFASST on the data structures.
         * Here, \\(a\\) is a time point and \\(x\\) another data structure (usually of the
         * same type).
         */
        virtual void saxpy(time /*a*/, shared_ptr<const Encapsulation<time>> /*x*/)
        {
          throw NotImplementedYet("encap");
        }

        /**
         * defines matrix-vector multiplication for this data type.
         */
        virtual void mat_apply(vector<shared_ptr<Encapsulation<time>>> dst, time a, matrix<time> mat,
                               vector<shared_ptr<Encapsulation<time>>> src, bool zero = true)
        {
          size_t ndst = dst.size();
          size_t nsrc = src.size();

          if (zero) {
            for (auto elem : dst) { elem->zero(); }
          }

          for (size_t n = 0; n < ndst; n++) {
            for (size_t m = 0; m < nsrc; m++) {
              auto s = mat(n, m);
              if (s != 0.0) {
                dst[n]->saxpy(a*s, src[m]);
              }
            }
          }
        }
        //! @}
    };

    template<typename time = time_precision>
    class EncapFactory
    {
      public:
        virtual shared_ptr<Encapsulation<time>> create(const EncapType) = 0;
    };

  }
}

#endif
<|endoftext|>


<commit_before>/*
 * cookie.hpp
 *
 *  Created on: Aug 26, 2015
 *      Author: zmij
 */

#ifndef PUSHKIN_HTTP_COMMON_COOKIE_HPP_
#define PUSHKIN_HTTP_COMMON_COOKIE_HPP_

#include <string>
#include <vector>

#include <boost/date_time.hpp>
#include <boost/optional.hpp>

#include <tip/iri.hpp>

namespace psst {
namespace http {

struct cookie {
	using host_opt      = ::boost::optional< ::tip::iri::host >;
	using path_opt      = ::boost::optional< ::tip::iri::path >;
	using int_opt       = ::boost::optional< ::std::int32_t >;
	using datetime_type = ::boost::posix_time::ptime;
	using datetime_opt  = ::boost::optional< datetime_type>;

	::std::string	name;
	::std::string	value;

	datetime_opt	expires;
	int_opt			max_age;
	host_opt		domain;
	path_opt		path;
	bool			secure;
	bool			http_only;
};

struct cookie_name_cmp {
	bool
	operator()(cookie const& lhs, cookie const& rhs)
	{
		return lhs.name < rhs.name;
	}
};

// TODO multiset?
using request_cookies = ::std::vector<cookie>;

}  // namespace http
}  // namespace psst

#endif /* PUSHKIN_HTTP_COMMON_COOKIE_HPP_ */
<commit_msg>[build] Fix const compatator warning<commit_after>/*
 * cookie.hpp
 *
 *  Created on: Aug 26, 2015
 *      Author: zmij
 */

#ifndef PUSHKIN_HTTP_COMMON_COOKIE_HPP_
#define PUSHKIN_HTTP_COMMON_COOKIE_HPP_

#include <string>
#include <vector>

#include <boost/date_time.hpp>
#include <boost/optional.hpp>

#include <tip/iri.hpp>

namespace psst {
namespace http {

struct cookie {
	using host_opt      = ::boost::optional< ::tip::iri::host >;
	using path_opt      = ::boost::optional< ::tip::iri::path >;
	using int_opt       = ::boost::optional< ::std::int32_t >;
	using datetime_type = ::boost::posix_time::ptime;
	using datetime_opt  = ::boost::optional< datetime_type>;

	::std::string	name;
	::std::string	value;

	datetime_opt	expires;
	int_opt			max_age;
	host_opt		domain;
	path_opt		path;
	bool			secure;
	bool			http_only;
};

struct cookie_name_cmp {
	bool
	operator()(cookie const& lhs, cookie const& rhs) const
	{
		return lhs.name < rhs.name;
	}
};

// TODO multiset?
using request_cookies = ::std::vector<cookie>;

}  // namespace http
}  // namespace psst

#endif /* PUSHKIN_HTTP_COMMON_COOKIE_HPP_ */
<|endoftext|>


<commit_before>#ifndef _INCLUDED_LZW_DEBUG_CODER_HPP_
#define _INCLUDED_LZW_DEBUG_CODER_HPP_

#include <tudocomp/Coder.hpp>

#include <tudocomp/lz78/trie.h>
#include <tudocomp/lz78/Lz78DecodeBuffer.hpp>

#include <tudocomp/lzw/factor.h>

namespace tudocomp {

namespace lzw {

using ::lzw::LzwEntry;

/**
 * Encodes factors as simple strings.
 */
class LzwDebugCoder {
private:
    // TODO: Change encode_* methods to not take Output& since that inital setup
    // rather, have a single init location
    tudocomp::output::StreamGuard m_out;

public:
    inline LzwDebugCoder(Env& env, Output& out)
        : m_out(out.as_stream())
    {
    }

    inline LzwDebugCoder(Env& env, Output& out, size_t len)
        : m_out(out.as_stream())
    {
    }

    inline ~LzwDebugCoder() {
        (*m_out).flush();
    }

    inline void encode_sym(uint8_t sym) {
        throw std::runtime_error("encoder does not support encoding raw symbols");
    }

    inline void encode_fact(const LzwEntry& entry) {
        if (entry >= 32u && entry <= 127u) {
            (*m_out) << "'" << char(uint8_t(entry)) << "',";
        } else {
            (*m_out) << uint64_t(entry) << ",";
        }
    }

    inline static void decode(Input& _inp, Output& _out) {
        auto iguard = _inp.as_stream();
        auto oguard = _out.as_stream();
        auto& inp = *iguard;
        auto& out = *oguard;

        bool more = true;
        char c = '?';
        decode_step([&]() -> LzwEntry {
            if (!more) {
                return LzwEntry(-1);
            }

            LzwEntry v;
            more &= parse_number_until_other(inp, c, v);

            if (more && c == '\'') {
                more &= bool(inp.get(c));
                v = uint8_t(c);
                more &= bool(inp.get(c));
                DCHECK(c == '\'');
                more &= bool(inp.get(c));
            }

            if (more) {
                DCHECK(c == ',');
            }

            if (!more) {
                return LzwEntry(-1);
            }
            //std::cout << byte_to_nice_ascii_char(v) << "\n";
            return v;

        }, out);
    }
};

}

}

#endif
<commit_msg>Fixed missing include<commit_after>#ifndef _INCLUDED_LZW_DEBUG_CODER_HPP_
#define _INCLUDED_LZW_DEBUG_CODER_HPP_

#include <tudocomp/Coder.hpp>

#include <tudocomp/lz78/trie.h>
#include <tudocomp/lz78/Lz78DecodeBuffer.hpp>

#include <tudocomp/lzw/factor.h>
#include <tudocomp/lzw/decode.hpp>

namespace tudocomp {

namespace lzw {

using ::lzw::LzwEntry;

/**
 * Encodes factors as simple strings.
 */
class LzwDebugCoder {
private:
    // TODO: Change encode_* methods to not take Output& since that inital setup
    // rather, have a single init location
    tudocomp::output::StreamGuard m_out;

public:
    inline LzwDebugCoder(Env& env, Output& out)
        : m_out(out.as_stream())
    {
    }

    inline LzwDebugCoder(Env& env, Output& out, size_t len)
        : m_out(out.as_stream())
    {
    }

    inline ~LzwDebugCoder() {
        (*m_out).flush();
    }

    inline void encode_sym(uint8_t sym) {
        throw std::runtime_error("encoder does not support encoding raw symbols");
    }

    inline void encode_fact(const LzwEntry& entry) {
        if (entry >= 32u && entry <= 127u) {
            (*m_out) << "'" << char(uint8_t(entry)) << "',";
        } else {
            (*m_out) << uint64_t(entry) << ",";
        }
    }

    inline static void decode(Input& _inp, Output& _out) {
        auto iguard = _inp.as_stream();
        auto oguard = _out.as_stream();
        auto& inp = *iguard;
        auto& out = *oguard;

        bool more = true;
        char c = '?';
        decode_step([&]() -> LzwEntry {
            if (!more) {
                return LzwEntry(-1);
            }

            LzwEntry v;
            more &= parse_number_until_other(inp, c, v);

            if (more && c == '\'') {
                more &= bool(inp.get(c));
                v = uint8_t(c);
                more &= bool(inp.get(c));
                DCHECK(c == '\'');
                more &= bool(inp.get(c));
            }

            if (more) {
                DCHECK(c == ',');
            }

            if (!more) {
                return LzwEntry(-1);
            }
            //std::cout << byte_to_nice_ascii_char(v) << "\n";
            return v;

        }, out);
    }
};

}

}

#endif
<|endoftext|>


<commit_before>/************************************************************************/
/*                                                                      */
/*     Copyright 2013-2014 by Martin Bidlingmaier and Ullrich Koethe    */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    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.                                   */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_BLOCKWISE_WATERSHEDS_HXX
#define VIGRA_BLOCKWISE_WATERSHEDS_HXX

#include "multi_array.hxx"
#include "multi_gridgraph.hxx"
#include "blockify.hxx"
#include "blockwise_labeling.hxx"
#include "overlapped_blocks.hxx"

#include <limits>

namespace vigra
{

namespace blockwise_watersheds_detail
{

template <class DataArray, class DirectionsBlocksIterator>
void prepareBlockwiseWatersheds(const Overlaps<DataArray>& overlaps,
                                DirectionsBlocksIterator directions_blocks_begin,
                                NeighborhoodType neighborhood)
{
    static const unsigned int N = DataArray::actual_dimension;
    typedef typename MultiArrayShape<N>::type Shape;
    typedef typename DirectionsBlocksIterator::value_type DirectionsBlock;
    Shape shape = overlaps.shape();
    vigra_assert(shape == directions_blocks_begin.shape(), "");

    MultiCoordinateIterator<N> it(shape);
    MultiCoordinateIterator<N> end = it.getEndIterator();
    for( ; it != end; ++it)
    {
        DirectionsBlock directions_block = directions_blocks_begin[*it];
        OverlappingBlock<DataArray> data_block = overlaps[*it];

        typedef GridGraph<N, undirected_tag> Graph;
        typedef typename Graph::NodeIt GraphScanner;
        typedef typename Graph::OutArcIt NeighborIterator;

        Graph graph(data_block.block.shape(), neighborhood);
        for(GraphScanner node(graph); node != lemon::INVALID; ++node)
        {
            if(within(*node, data_block.inner_bounds))
            {
                typedef typename DataArray::value_type Data;
                Data lowest_neighbor = data_block.block[*node];

                typedef typename DirectionsBlock::value_type Direction;
                Direction lowest_neighbor_direction = std::numeric_limits<unsigned short>::max();

                for(NeighborIterator arc(graph, *node); arc != lemon::INVALID; ++arc)
                {
                    Shape neighbor_coordinates = graph.target(*arc);
                    Data neighbor_data = data_block.block[neighbor_coordinates];
                    if(neighbor_data < lowest_neighbor)
                    {
                        lowest_neighbor = neighbor_data;
                        lowest_neighbor_direction = arc.neighborIndex();
                    }
                }
                directions_block[*node - data_block.inner_bounds.first] = lowest_neighbor_direction;
            }
        }
    }
}

template <unsigned int N>
struct UnionFindWatershedEquality
{
    // FIXME: this graph object shouldn't be necessary, most functions (and state) of graph are not used
    // this probably needs some refactoring in GridGraph
    GridGraph<N, undirected_tag>* graph;

    template <class Shape>
    bool operator()(unsigned short u, const unsigned short v, const Shape& diff) const
    {
        static const unsigned short plateau_id = std::numeric_limits<unsigned short>::max();
        return (u == plateau_id && v == plateau_id) ||
               (u != plateau_id && graph->neighborOffset(u) == diff) ||
               (v != plateau_id && graph->neighborOffset(graph->oppositeIndex(v)) == diff);
    }

    struct WithDiffTag
    {};
};

} // namespace blockwise_watersheds_detail

template <unsigned int N, class Data, class S1,
                          class Label, class S2>
Label unionFindWatershedBlockwise(MultiArrayView<N, Data, S1> data,
                                  MultiArrayView<N, Label, S2> labels,
                                  NeighborhoodType neighborhood = DirectNeighborhood,
                                  const typename MultiArrayView<N, Data, S1>::difference_type& block_shape =
                                          typename MultiArrayView<N, Data, S1>::difference_type(128))
{
    using namespace blockwise_watersheds_detail;

    typedef typename MultiArrayView<N, Data, S1>::difference_type Shape;
    Shape shape = data.shape();
    vigra_precondition(shape == labels.shape(), "shapes of data and labels do not match");

    MultiArray<N, unsigned short> directions(shape);

    MultiArray<N, MultiArrayView<N, unsigned short> > directions_blocks = blockify(directions, block_shape);

    Overlaps<MultiArrayView<N, Data, S1> > overlaps(data, block_shape, Shape(1), Shape(1));
    prepareBlockwiseWatersheds(overlaps, directions_blocks.begin(), neighborhood);
    GridGraph<N, undirected_tag> graph(data.shape(), neighborhood);
    UnionFindWatershedEquality<N> equal = {&graph};
    return labelMultiArrayBlockwise(directions, labels, LabelOptions().neighborhood(neighborhood).blockShape(block_shape), equal);
}

template <unsigned int N, class Data,
                          class Label>
Label unionFindWatershedBlockwise(const ChunkedArray<N, Data>& data,
                                  ChunkedArray<N, Label>& labels,
                                  NeighborhoodType neighborhood,
                                  ChunkedArray<N, unsigned short>& directions)
{
    using namespace blockwise_watersheds_detail;

    typedef typename ChunkedArray<N, Data>::shape_type Shape;
    Shape shape = data.shape();
    vigra_precondition(shape == labels.shape() && shape == directions.shape(), "shapes of data and labels do not match");
    Shape chunk_shape = data.chunkShape();
    vigra_precondition(chunk_shape == labels.chunkShape() && chunk_shape == directions.chunkShape(), "chunk shapes do not match");

    Overlaps<ChunkedArray<N, Data> > overlaps(data, data.chunkShape(), Shape(1), Shape(1));

    prepareBlockwiseWatersheds(overlaps, directions.chunk_begin(Shape(0), shape), neighborhood);

    GridGraph<N, undirected_tag> graph(shape, neighborhood);
    UnionFindWatershedEquality<N> equal = {&graph};
    return labelMultiArrayBlockwise(directions, labels, LabelOptions().neighborhood(neighborhood), equal);
}

template <unsigned int N, class Data,
                          class Label>
inline Label
unionFindWatershedBlockwise(const ChunkedArray<N, Data>& data,
                                  ChunkedArray<N, Label>& labels,
                                  NeighborhoodType neighborhood = DirectNeighborhood)
{
    ChunkedArrayLazy<N, unsigned short> directions(data.shape(), data.chunkShape());
    return unionFindWatershedBlockwise(data, labels, neighborhood, directions);
}

} // namespace vigra

#endif // VIGRA_BLOCKWISE_WATERSHEDS_HXX
<commit_msg>add documentation<commit_after>/************************************************************************/
/*                                                                      */
/*     Copyright 2013-2014 by Martin Bidlingmaier and Ullrich Koethe    */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    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.                                   */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_BLOCKWISE_WATERSHEDS_HXX
#define VIGRA_BLOCKWISE_WATERSHEDS_HXX

#include "multi_array.hxx"
#include "multi_gridgraph.hxx"
#include "blockify.hxx"
#include "blockwise_labeling.hxx"
#include "overlapped_blocks.hxx"

#include <limits>

namespace vigra
{

/** \addtogroup SeededRegionGrowing
*/
//@{

namespace blockwise_watersheds_detail
{

template <class DataArray, class DirectionsBlocksIterator>
void prepareBlockwiseWatersheds(const Overlaps<DataArray>& overlaps,
                                DirectionsBlocksIterator directions_blocks_begin,
                                NeighborhoodType neighborhood)
{
    static const unsigned int N = DataArray::actual_dimension;
    typedef typename MultiArrayShape<N>::type Shape;
    typedef typename DirectionsBlocksIterator::value_type DirectionsBlock;
    Shape shape = overlaps.shape();
    vigra_assert(shape == directions_blocks_begin.shape(), "");

    MultiCoordinateIterator<N> it(shape);
    MultiCoordinateIterator<N> end = it.getEndIterator();
    for( ; it != end; ++it)
    {
        DirectionsBlock directions_block = directions_blocks_begin[*it];
        OverlappingBlock<DataArray> data_block = overlaps[*it];

        typedef GridGraph<N, undirected_tag> Graph;
        typedef typename Graph::NodeIt GraphScanner;
        typedef typename Graph::OutArcIt NeighborIterator;

        Graph graph(data_block.block.shape(), neighborhood);
        for(GraphScanner node(graph); node != lemon::INVALID; ++node)
        {
            if(within(*node, data_block.inner_bounds))
            {
                typedef typename DataArray::value_type Data;
                Data lowest_neighbor = data_block.block[*node];

                typedef typename DirectionsBlock::value_type Direction;
                Direction lowest_neighbor_direction = std::numeric_limits<unsigned short>::max();

                for(NeighborIterator arc(graph, *node); arc != lemon::INVALID; ++arc)
                {
                    Shape neighbor_coordinates = graph.target(*arc);
                    Data neighbor_data = data_block.block[neighbor_coordinates];
                    if(neighbor_data < lowest_neighbor)
                    {
                        lowest_neighbor = neighbor_data;
                        lowest_neighbor_direction = arc.neighborIndex();
                    }
                }
                directions_block[*node - data_block.inner_bounds.first] = lowest_neighbor_direction;
            }
        }
    }
}

template <unsigned int N>
struct UnionFindWatershedEquality
{
    // FIXME: this graph object shouldn't be necessary, most functions (and state) of graph are not used
    // this probably needs some refactoring in GridGraph
    GridGraph<N, undirected_tag>* graph;

    template <class Shape>
    bool operator()(unsigned short u, const unsigned short v, const Shape& diff) const
    {
        static const unsigned short plateau_id = std::numeric_limits<unsigned short>::max();
        return (u == plateau_id && v == plateau_id) ||
               (u != plateau_id && graph->neighborOffset(u) == diff) ||
               (v != plateau_id && graph->neighborOffset(graph->oppositeIndex(v)) == diff);
    }

    struct WithDiffTag
    {};
};

} // namespace blockwise_watersheds_detail

template <unsigned int N, class Data, class S1,
                          class Label, class S2>
Label unionFindWatershedBlockwise(MultiArrayView<N, Data, S1> data,
                                  MultiArrayView<N, Label, S2> labels,
                                  NeighborhoodType neighborhood = DirectNeighborhood,
                                  const typename MultiArrayView<N, Data, S1>::difference_type& block_shape =
                                          typename MultiArrayView<N, Data, S1>::difference_type(128))
{
    using namespace blockwise_watersheds_detail;

    typedef typename MultiArrayView<N, Data, S1>::difference_type Shape;
    Shape shape = data.shape();
    vigra_precondition(shape == labels.shape(), "shapes of data and labels do not match");

    MultiArray<N, unsigned short> directions(shape);

    MultiArray<N, MultiArrayView<N, unsigned short> > directions_blocks = blockify(directions, block_shape);

    Overlaps<MultiArrayView<N, Data, S1> > overlaps(data, block_shape, Shape(1), Shape(1));
    prepareBlockwiseWatersheds(overlaps, directions_blocks.begin(), neighborhood);
    GridGraph<N, undirected_tag> graph(data.shape(), neighborhood);
    UnionFindWatershedEquality<N> equal = {&graph};
    return labelMultiArrayBlockwise(directions, labels, LabelOptions().neighborhood(neighborhood).blockShape(block_shape), equal);
}

/*************************************************************/
/*                                                           */
/*                      unionFindWatershedBlockwise          */
/*                                                           */
/*************************************************************/

/** \brief Blockise union-find watershed transform for ChunkedArrays.

     Declaration:

    \code
    namespace vigra {

        template <unsigned int N, class Data, class Label>
        Label unionFindWatershedBlockwise(const ChunkedArray<N, Data>& data,
                                          ChunkedArray<N, Label>& labels,
                                          NeighborhoodType neighborhood = DirectNeighborhood);

        // provide temporary directions storage
        template <unsigned int N, class Data, class Label>
        Label unionFindWatershedBlockwise(const ChunkedArray<N, Data>& data,
                                          ChunkedArray<N, Label>& labels,
                                          NeighborhoodType neighborhood,
                                          ChunkedArray<N, unsigned short>& temporary_storage);

    }
    \endcode

    The resulting labeling is equivalent to a labeling by \ref watershedsUnionFind, that is,
    the components are the same but may have different ids.
    If \a temporary_storage is provided, this array is used for intermediate result storage.
    Otherwise, a newly created \ref ChunkedArrayLazy is used.

    Return: the number of labels assigned (=largest label, because labels start at one)

     Usage:

    \#include  \<vigra/blockwise_labeling.hxx\>

    Namespace: vigra

    \code
    Shape3 shape = Shape3(10);
    Shape3 chunk_shape = Shape3(4);
    ChunkedArrayLazy<3, int> data(shape, chunk_shape);
    // fill data ...

    ChunkedArrayLazy<3, size_t> labels(shape, chunk_shape);

    unionFindWatershedBlockwise(data, labels, IndirectNeighborhood);
    \endcode
    */
doxygen_overloaded_function(template <...> unsigned int unionFindWatershedBlockwise)

template <unsigned int N, class Data, class Label>
Label unionFindWatershedBlockwise(const ChunkedArray<N, Data>& data,
                                  ChunkedArray<N, Label>& labels,
                                  NeighborhoodType neighborhood,
                                  ChunkedArray<N, unsigned short>& directions)
{
    using namespace blockwise_watersheds_detail;

    typedef typename ChunkedArray<N, Data>::shape_type Shape;
    Shape shape = data.shape();
    vigra_precondition(shape == labels.shape() && shape == directions.shape(), "shapes of data and labels do not match");
    Shape chunk_shape = data.chunkShape();
    vigra_precondition(chunk_shape == labels.chunkShape() && chunk_shape == directions.chunkShape(), "chunk shapes do not match");

    Overlaps<ChunkedArray<N, Data> > overlaps(data, data.chunkShape(), Shape(1), Shape(1));

    prepareBlockwiseWatersheds(overlaps, directions.chunk_begin(Shape(0), shape), neighborhood);

    GridGraph<N, undirected_tag> graph(shape, neighborhood);
    UnionFindWatershedEquality<N> equal = {&graph};
    return labelMultiArrayBlockwise(directions, labels, LabelOptions().neighborhood(neighborhood), equal);
}

template <unsigned int N, class Data,
                          class Label>
inline Label
unionFindWatershedBlockwise(const ChunkedArray<N, Data>& data,
                                  ChunkedArray<N, Label>& labels,
                                  NeighborhoodType neighborhood = DirectNeighborhood)
{
    ChunkedArrayLazy<N, unsigned short> directions(data.shape(), data.chunkShape());
    return unionFindWatershedBlockwise(data, labels, neighborhood, directions);
}

//@}

} // namespace vigra

#endif // VIGRA_BLOCKWISE_WATERSHEDS_HXX
<|endoftext|>