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

/*!
 * \file
 * \brief Implementation of a Convolutional Restricted Boltzmann Machine
 */

#pragma once

#include <cstddef>
#include <ctime>
#include <random>

#include "cpp_utils/assert.hpp"     //Assertions
#include "cpp_utils/stop_watch.hpp" //Performance counter
#include "cpp_utils/maybe_parallel.hpp"

#include "etl/etl.hpp"

#include "standard_conv_rbm.hpp" //The base class
#include "rbm_tmp.hpp"           // static_if macros

namespace dll {

/*!
 * \brief Convolutional Restricted Boltzmann Machine
 *
 * This follows the definition of a CRBM by Honglak Lee.
 */
template <typename Derived, typename Desc>
struct standard_crbm : public standard_conv_rbm<Derived, Desc> {
    using derived_t = Derived;                          ///< The derived type
    using desc      = Desc;                             ///< The descriptor of the layer
    using weight    = typename desc::weight;            ///< The data type for this layer
    using this_type = standard_crbm<derived_t, desc>;   ///< The type of this layer
    using base_type = standard_conv_rbm<Derived, desc>; ///< The base type
    using layer_t     = this_type;                     ///< This layer's type
    using dyn_layer_t = typename desc::dyn_layer_t;    ///< The dynamic version of this layer

    using input_one_t  = typename rbm_base_traits<derived_t>::input_one_t;  ///< The type of one input
    using output_one_t = typename rbm_base_traits<derived_t>::output_one_t; ///< The type of one output
    using input_t      = typename rbm_base_traits<derived_t>::input_t;      ///< The type of the input
    using output_t     = typename rbm_base_traits<derived_t>::output_t;     ///< The type of the output

    static constexpr unit_type visible_unit = desc::visible_unit; ///< The visible unit type
    static constexpr unit_type hidden_unit  = desc::hidden_unit;  ///< The hidden unit type

    standard_crbm() = default;

    // Make base class them participate in overload resolution
    using base_type::activate_hidden;
    using base_type::batch_activate_hidden;

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void activate_hidden(H1&& h_a, H2&& h_s, const V1& v_a, const V2& /*v_s*/) const {
        dll::auto_timer timer("crbm:activate_hidden");

        static_assert(hidden_unit == unit_type::BINARY || is_relu(hidden_unit), "Invalid hidden unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2>();

        using namespace etl;

        // TODO This code is a huge mess!

        auto b_rep = as_derived().get_b_rep();

        as_derived().reshape_h_a(h_a) = etl::conv_4d_valid_flipped(as_derived().reshape_v_a(v_a), as_derived().w);

        // Need to be done before h_a is computed!

        if constexpr (P && S && hidden_unit == unit_type::RELU) {
            h_s = max(logistic_noise(b_rep + h_a), 0.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU1) {
            h_s = min(max(ranged_noise(b_rep + h_a, 1.0), 0.0), 1.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU6) {
            h_s = min(max(ranged_noise(b_rep + h_a, 6.0), 0.0), 6.0);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::BINARY) {
            h_a = etl::sigmoid(b_rep + h_a);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::GAUSSIAN) {
            h_a = etl::sigmoid((1.0 / (0.1 * 0.1)) >> (b_rep + h_a));
        }

        if constexpr (P && hidden_unit == unit_type::RELU) {
            h_a = max(b_rep + h_a, 0.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU1) {
            h_a = min(max(b_rep + h_a, 0.0), 1.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU6) {
            h_a = min(max(b_rep + h_a, 0.0), 6.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::BINARY) {
            h_s = bernoulli(h_a);
        }

        // NaN checks

        if (P) {
            nan_check_deep(h_a);
        }

        if (S) {
            nan_check_deep(h_s);
        }
    }

    template<typename Input>
    void activate_hidden(output_one_t& h_a, const Input& input) const {
        activate_hidden<true, false>(h_a, h_a, input, input);
    }

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void activate_visible(const H1& /*h_a*/, const H2& h_s, V1&& v_a, V2&& v_s) const {
        dll::auto_timer timer("crbm:activate_visible");

        static_assert(visible_unit == unit_type::BINARY || visible_unit == unit_type::GAUSSIAN, "Invalid visible unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2>();

        using namespace etl;

        // Note: we reuse v_a as a temporary here, before adding the biases
        as_derived().reshape_v_a(v_a) = etl::conv_4d_full(as_derived().reshape_h_a(h_s), as_derived().w);

        auto c_rep = as_derived().get_c_rep();

        // Compute the activation probabilities

        if constexpr (P && visible_unit == unit_type::BINARY) {
            v_a = etl::sigmoid(c_rep + v_a);
        }

        if constexpr (P && visible_unit == unit_type::GAUSSIAN) {
            v_a = c_rep + v_a;
        }

        // Sample the values from the probabilities

        if constexpr (P && S && visible_unit == unit_type::BINARY) {
            v_s = bernoulli(v_a);
        }

        if constexpr (P && S && visible_unit == unit_type::GAUSSIAN) {
            v_s = normal_noise(v_a);
        }

        // NaN checks

        if (P) {
            nan_check_deep(v_a);
        }

        if (S) {
            nan_check_deep(v_s);
        }
    }

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void batch_activate_hidden(H1&& h_a, H2&& h_s, const V1& v_a, const V2& /*v_s*/) const {
        dll::auto_timer timer("crbm:batch_activate_hidden");

        static_assert(hidden_unit == unit_type::BINARY || is_relu(hidden_unit), "Invalid hidden unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2, 1>();

        using namespace etl;

        // TODO This code is a huge mess!

        h_a = etl::conv_4d_valid_flipped(v_a, as_derived().w);

        auto b_rep = as_derived().get_batch_b_rep(v_a);

        // Need to be done before h_a is computed!
        if constexpr (P && S && hidden_unit == unit_type::RELU) {
            h_s = max(logistic_noise(b_rep + h_a), 0.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU1) {
            h_s = min(max(ranged_noise(b_rep + h_a, 1.0), 0.0), 1.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU6) {
            h_s = min(max(ranged_noise(b_rep + h_a, 6.0), 0.0), 6.0);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::BINARY) {
            h_a = etl::sigmoid(b_rep + h_a);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::GAUSSIAN) {
            h_a = etl::sigmoid((1.0 / (0.1 * 0.1)) >> (b_rep + h_a));
        }

        if constexpr (P && hidden_unit == unit_type::RELU) {
            h_a = max(b_rep + h_a, 0.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU1) {
            h_a = min(max(b_rep + h_a, 0.0), 1.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU6) {
            h_a = min(max(b_rep + h_a, 0.0), 6.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::BINARY) {
            h_s = bernoulli(h_a);
        }

        // NaN checks

        if (P) {
            nan_check_deep(h_a);
        }

        if (S) {
            nan_check_deep(h_s);
        }
    }

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void batch_activate_visible(const H1& /*h_a*/, const H2& h_s, V1&& v_a, V2&& v_s) const {
        dll::auto_timer timer("crbm:batch_activate_visible");

        static_assert(visible_unit == unit_type::BINARY || visible_unit == unit_type::GAUSSIAN, "Invalid visible unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2, 1>();

        // Note: we reuse v_a as a temporary here, before adding the biases
        v_a = etl::conv_4d_full(h_s, as_derived().w);

        auto c_rep = as_derived().get_batch_c_rep(h_s);

        // Compute the activation probabilities

        if constexpr (P && visible_unit == unit_type::BINARY) {
            v_a = etl::sigmoid(c_rep + v_a);
        }

        if constexpr (P && visible_unit == unit_type::GAUSSIAN) {
            v_a = c_rep + v_a;
        }

        // Sample the values from the probabilities

        if constexpr (P && S && visible_unit == unit_type::BINARY) {
            v_s = bernoulli(v_a);
        }

        if constexpr (P && S && visible_unit == unit_type::GAUSSIAN) {
            v_s = normal_noise(v_a);
        }

        // NaN Checks

        if (P) {
            nan_check_deep(v_a);
        }

        if (S) {
            nan_check_deep(v_s);
        }
    }

    friend base_type;

private:
    template<typename Input, typename Out>
    weight energy_impl(const Input& v, const Out& h) const {
        static_assert(etl::is_etl_expr<Out>, "energy_impl works with ETL expressions only");

        auto rv = as_derived().reshape_v_a(v);
        auto tmp = as_derived().energy_tmp();
        tmp = etl::conv_4d_valid_flipped(rv, as_derived().w);

        if constexpr (desc::visible_unit == unit_type::BINARY && desc::hidden_unit == unit_type::BINARY) {
            //Definition according to Honglak Lee
            //E(v,h) = - sum_k hk . (Wk*v) - sum_k bk sum_h hk - c sum_v v

            return -etl::sum(as_derived().c >> etl::sum_r(rv(0))) - etl::sum(as_derived().b >> etl::sum_r(h)) - etl::sum(h >> tmp(0));
        } else if constexpr (desc::visible_unit == unit_type::GAUSSIAN && desc::hidden_unit == unit_type::BINARY) {
            //Definition according to Honglak Lee / Mixed with Gaussian
            //E(v,h) = - sum_k hk . (Wk*v) - sum_k bk sum_h hk - sum_v ((v - c) ^ 2 / 2)

            auto c_rep = as_derived().get_c_rep();
            return -sum(etl::pow(rv(0) - c_rep, 2) / 2.0) - etl::sum(as_derived().b >> etl::sum_r(h)) - etl::sum(h >> tmp(0));
        } else {
            return 0.0;
        }
    }

    template<typename Input>
    weight free_energy_impl(const Input& v) const {
        auto rv = as_derived().reshape_v_a(v);
        auto tmp = as_derived().energy_tmp();
        tmp = etl::conv_4d_valid_flipped(rv, as_derived().w);

        if constexpr (desc::visible_unit == unit_type::BINARY && desc::hidden_unit == unit_type::BINARY) {
            //Definition computed from E(v,h)

            auto b_rep = as_derived().get_b_rep();
            auto x = b_rep + tmp(0);
            return -etl::sum(as_derived().c >> etl::sum_r(rv(0))) - etl::sum(etl::log(1.0 + etl::exp(x)));
        } else if constexpr (desc::visible_unit == unit_type::GAUSSIAN && desc::hidden_unit == unit_type::BINARY) {
            //Definition computed from E(v,h)

            auto b_rep = as_derived().get_b_rep();
            auto x = b_rep + tmp(0);
            auto c_rep = as_derived().get_c_rep();
            return -sum(etl::pow(rv(0) - c_rep, 2) / 2.0) - etl::sum(etl::log(1.0 + etl::exp(x)));
        } else {
            return 0.0;
        }
    }

    /*!
     * \brief Returns a reference to the derived object, i.e. the object using the CRTP injector.
     * \return a reference to the derived object.
     */
    derived_t& as_derived() {
        return *static_cast<derived_t*>(this);
    }

    /*!
     * \brief Returns a reference to the derived object, i.e. the object using the CRTP injector.
     * \return a reference to the derived object.
     */
    const derived_t& as_derived() const {
        return *static_cast<const derived_t*>(this);
    }
};

} //end of dll namespace
<commit_msg>CRBM: Proper use of bias_add_4d<commit_after>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Implementation of a Convolutional Restricted Boltzmann Machine
 */

#pragma once

#include <cstddef>
#include <ctime>
#include <random>

#include "cpp_utils/assert.hpp"     //Assertions
#include "cpp_utils/stop_watch.hpp" //Performance counter
#include "cpp_utils/maybe_parallel.hpp"

#include "etl/etl.hpp"

#include "standard_conv_rbm.hpp" //The base class
#include "rbm_tmp.hpp"           // static_if macros

namespace dll {

/*!
 * \brief Convolutional Restricted Boltzmann Machine
 *
 * This follows the definition of a CRBM by Honglak Lee.
 */
template <typename Derived, typename Desc>
struct standard_crbm : public standard_conv_rbm<Derived, Desc> {
    using derived_t = Derived;                          ///< The derived type
    using desc      = Desc;                             ///< The descriptor of the layer
    using weight    = typename desc::weight;            ///< The data type for this layer
    using this_type = standard_crbm<derived_t, desc>;   ///< The type of this layer
    using base_type = standard_conv_rbm<Derived, desc>; ///< The base type
    using layer_t     = this_type;                     ///< This layer's type
    using dyn_layer_t = typename desc::dyn_layer_t;    ///< The dynamic version of this layer

    using input_one_t  = typename rbm_base_traits<derived_t>::input_one_t;  ///< The type of one input
    using output_one_t = typename rbm_base_traits<derived_t>::output_one_t; ///< The type of one output
    using input_t      = typename rbm_base_traits<derived_t>::input_t;      ///< The type of the input
    using output_t     = typename rbm_base_traits<derived_t>::output_t;     ///< The type of the output

    static constexpr unit_type visible_unit = desc::visible_unit; ///< The visible unit type
    static constexpr unit_type hidden_unit  = desc::hidden_unit;  ///< The hidden unit type

    standard_crbm() = default;

    // Make base class them participate in overload resolution
    using base_type::activate_hidden;
    using base_type::batch_activate_hidden;

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void activate_hidden(H1&& h_a, H2&& h_s, const V1& v_a, const V2& /*v_s*/) const {
        dll::auto_timer timer("crbm:activate_hidden");

        static_assert(hidden_unit == unit_type::BINARY || is_relu(hidden_unit), "Invalid hidden unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2>();

        using namespace etl;

        // TODO This code is a huge mess!

        auto b_rep = as_derived().get_b_rep();

        as_derived().reshape_h_a(h_a) = etl::conv_4d_valid_flipped(as_derived().reshape_v_a(v_a), as_derived().w);

        // Need to be done before h_a is computed!

        if constexpr (P && S && hidden_unit == unit_type::RELU) {
            h_s = max(logistic_noise(b_rep + h_a), 0.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU1) {
            h_s = min(max(ranged_noise(b_rep + h_a, 1.0), 0.0), 1.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU6) {
            h_s = min(max(ranged_noise(b_rep + h_a, 6.0), 0.0), 6.0);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::BINARY) {
            h_a = etl::sigmoid(b_rep + h_a);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::GAUSSIAN) {
            h_a = etl::sigmoid((1.0 / (0.1 * 0.1)) >> (b_rep + h_a));
        }

        if constexpr (P && hidden_unit == unit_type::RELU) {
            h_a = max(b_rep + h_a, 0.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU1) {
            h_a = min(max(b_rep + h_a, 0.0), 1.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU6) {
            h_a = min(max(b_rep + h_a, 0.0), 6.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::BINARY) {
            h_s = bernoulli(h_a);
        }

        // NaN checks

        if (P) {
            nan_check_deep(h_a);
        }

        if (S) {
            nan_check_deep(h_s);
        }
    }

    template<typename Input>
    void activate_hidden(output_one_t& h_a, const Input& input) const {
        activate_hidden<true, false>(h_a, h_a, input, input);
    }

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void activate_visible(const H1& /*h_a*/, const H2& h_s, V1&& v_a, V2&& v_s) const {
        dll::auto_timer timer("crbm:activate_visible");

        static_assert(visible_unit == unit_type::BINARY || visible_unit == unit_type::GAUSSIAN, "Invalid visible unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2>();

        using namespace etl;

        // Note: we reuse v_a as a temporary here, before adding the biases
        as_derived().reshape_v_a(v_a) = etl::conv_4d_full(as_derived().reshape_h_a(h_s), as_derived().w);

        auto c_rep = as_derived().get_c_rep();

        // Compute the activation probabilities

        if constexpr (P && visible_unit == unit_type::BINARY) {
            v_a = etl::sigmoid(c_rep + v_a);
        }

        if constexpr (P && visible_unit == unit_type::GAUSSIAN) {
            v_a = c_rep + v_a;
        }

        // Sample the values from the probabilities

        if constexpr (P && S && visible_unit == unit_type::BINARY) {
            v_s = bernoulli(v_a);
        }

        if constexpr (P && S && visible_unit == unit_type::GAUSSIAN) {
            v_s = normal_noise(v_a);
        }

        // NaN checks

        if (P) {
            nan_check_deep(v_a);
        }

        if (S) {
            nan_check_deep(v_s);
        }
    }

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void batch_activate_hidden(H1&& h_a, H2&& h_s, const V1& v_a, const V2& /*v_s*/) const {
        dll::auto_timer timer("crbm:batch_activate_hidden");

        static_assert(hidden_unit == unit_type::BINARY || is_relu(hidden_unit), "Invalid hidden unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2, 1>();

        using namespace etl;

        // TODO This code is a huge mess!

        h_a = etl::conv_4d_valid_flipped(v_a, as_derived().w);

        // Need to be done before h_a is computed!
        if constexpr (P && S && hidden_unit == unit_type::RELU) {
            h_s = max(logistic_noise(bias_add_4d(h_a, as_derived().b)), 0.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU1) {
            h_s = min(max(ranged_noise(bias_add_4d(h_a, as_derived().b), 1.0), 0.0), 1.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::RELU6) {
            h_s = min(max(ranged_noise(bias_add_4d(h_a, as_derived().b), 6.0), 0.0), 6.0);
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::BINARY) {
            h_a = etl::sigmoid(bias_add_4d(h_a, as_derived().b));
        }

        if constexpr (P && hidden_unit == unit_type::BINARY && visible_unit == unit_type::GAUSSIAN) {
            h_a = etl::sigmoid((1.0 / (0.1 * 0.1)) >> (bias_add_4d(h_a, as_derived().b)));
        }

        if constexpr (P && hidden_unit == unit_type::RELU) {
            h_a = max(bias_add_4d(h_a, as_derived().b), 0.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU1) {
            h_a = min(max(bias_add_4d(h_a, as_derived().b), 0.0), 1.0);
        }

        if constexpr (P && hidden_unit == unit_type::RELU6) {
            h_a = min(max(bias_add_4d(h_a, as_derived().b), 0.0), 6.0);
        }

        if constexpr (P && S && hidden_unit == unit_type::BINARY) {
            h_s = bernoulli(h_a);
        }

        // NaN checks

        if (P) {
            nan_check_deep(h_a);
        }

        if (S) {
            nan_check_deep(h_s);
        }
    }

    template <bool P = true, bool S = true, typename H1, typename H2, typename V1, typename V2>
    void batch_activate_visible(const H1& /*h_a*/, const H2& h_s, V1&& v_a, V2&& v_s) const {
        dll::auto_timer timer("crbm:batch_activate_visible");

        static_assert(visible_unit == unit_type::BINARY || visible_unit == unit_type::GAUSSIAN, "Invalid visible unit type");
        static_assert(P, "Computing S without P is not implemented");

        as_derived().template validate_outputs<H1, H2, 1>();

        // Note: we reuse v_a as a temporary here, before adding the biases
        v_a = etl::conv_4d_full(h_s, as_derived().w);

        // Compute the activation probabilities

        if constexpr (P && visible_unit == unit_type::BINARY) {
            v_a = etl::sigmoid(bias_add_4d(v_a, as_derived().c));
        }

        if constexpr (P && visible_unit == unit_type::GAUSSIAN) {
            v_a = bias_add_4d(v_a, as_derived().c);
        }

        // Sample the values from the probabilities

        if constexpr (P && S && visible_unit == unit_type::BINARY) {
            v_s = bernoulli(v_a);
        }

        if constexpr (P && S && visible_unit == unit_type::GAUSSIAN) {
            v_s = normal_noise(v_a);
        }

        // NaN Checks

        if (P) {
            nan_check_deep(v_a);
        }

        if (S) {
            nan_check_deep(v_s);
        }
    }

    friend base_type;

private:
    template<typename Input, typename Out>
    weight energy_impl(const Input& v, const Out& h) const {
        static_assert(etl::is_etl_expr<Out>, "energy_impl works with ETL expressions only");

        auto rv = as_derived().reshape_v_a(v);
        auto tmp = as_derived().energy_tmp();
        tmp = etl::conv_4d_valid_flipped(rv, as_derived().w);

        if constexpr (desc::visible_unit == unit_type::BINARY && desc::hidden_unit == unit_type::BINARY) {
            //Definition according to Honglak Lee
            //E(v,h) = - sum_k hk . (Wk*v) - sum_k bk sum_h hk - c sum_v v

            return -etl::sum(as_derived().c >> etl::sum_r(rv(0))) - etl::sum(as_derived().b >> etl::sum_r(h)) - etl::sum(h >> tmp(0));
        } else if constexpr (desc::visible_unit == unit_type::GAUSSIAN && desc::hidden_unit == unit_type::BINARY) {
            //Definition according to Honglak Lee / Mixed with Gaussian
            //E(v,h) = - sum_k hk . (Wk*v) - sum_k bk sum_h hk - sum_v ((v - c) ^ 2 / 2)

            auto c_rep = as_derived().get_c_rep();
            return -sum(etl::pow(rv(0) - c_rep, 2) / 2.0) - etl::sum(as_derived().b >> etl::sum_r(h)) - etl::sum(h >> tmp(0));
        } else {
            return 0.0;
        }
    }

    template<typename Input>
    weight free_energy_impl(const Input& v) const {
        auto rv = as_derived().reshape_v_a(v);
        auto tmp = as_derived().energy_tmp();
        tmp = etl::conv_4d_valid_flipped(rv, as_derived().w);

        if constexpr (desc::visible_unit == unit_type::BINARY && desc::hidden_unit == unit_type::BINARY) {
            //Definition computed from E(v,h)

            auto b_rep = as_derived().get_b_rep();
            auto x = b_rep + tmp(0);
            return -etl::sum(as_derived().c >> etl::sum_r(rv(0))) - etl::sum(etl::log(1.0 + etl::exp(x)));
        } else if constexpr (desc::visible_unit == unit_type::GAUSSIAN && desc::hidden_unit == unit_type::BINARY) {
            //Definition computed from E(v,h)

            auto b_rep = as_derived().get_b_rep();
            auto x = b_rep + tmp(0);
            auto c_rep = as_derived().get_c_rep();
            return -sum(etl::pow(rv(0) - c_rep, 2) / 2.0) - etl::sum(etl::log(1.0 + etl::exp(x)));
        } else {
            return 0.0;
        }
    }

    /*!
     * \brief Returns a reference to the derived object, i.e. the object using the CRTP injector.
     * \return a reference to the derived object.
     */
    derived_t& as_derived() {
        return *static_cast<derived_t*>(this);
    }

    /*!
     * \brief Returns a reference to the derived object, i.e. the object using the CRTP injector.
     * \return a reference to the derived object.
     */
    const derived_t& as_derived() const {
        return *static_cast<const derived_t*>(this);
    }
};

} //end of dll namespace
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_v7
///
/// \macro_code
///
/// \date 2018-03-18
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!
/// \author Iliana Betsou

#include "ROOT/RCanvas.hxx"
#include "ROOT/RColor.hxx"
#include "ROOT/RText.hxx"
#include "ROOT/RLine.hxx"
#include "ROOT/RPadPos.hxx"
#include <string>

void lineWidthNew()
{
   using namespace ROOT::Experimental;

   auto canvas = RCanvas::Create("Canvas Title");
   double num = 0.3;

   auto style = std::make_shared<RStyleNew>();

   style->AddBlock("line").AddInt("line_style", 2).AddString("line_color_rgb", "4,5,6");

   for (int i=10; i>0; i--){
      num = num + 0.05;

      // current way to draw primitives - it always returns drawing options
      RPadPos pt(.3_normal, RPadLength::Normal(num));
      auto optts = canvas->Draw(RText(pt, std::to_string(i)));
      optts->SetSize(13).SetAlign(32).SetFont(52);

      RPadPos pl1(.32_normal, RPadLength::Normal(num));
      RPadPos pl2(.8_normal , RPadLength::Normal(num));

      // new way of drawing - return drawable itself, which has all kind attributes
      auto line = canvas->DrawNew<RLineNew>(pl1, pl2);

      // change line width
      line->AttrLine().SetWidth(i);

      printf("Current line width %f\n", line->AttrLine().GetWidth());

      // copy attributes
      auto attr = line->AttrLine();

      printf("Attribute line width %f\n", attr.GetWidth());

      // change attributes
      attr.SetWidth(i+1);

      line->AttrLine().Copy(attr);

      printf("Now line width %f\n", line->AttrLine().GetWidth());

      // assign style object to the attribute - now "Visitor" can use style as well
      line->AttrLine().UseStyle(style);

      printf("Afetr applying RStyle: width %f style %d color %s\n", line->AttrLine().GetWidth(), line->AttrLine().GetStyle(), line->AttrLine().Color().AsSVG().c_str());

      line->AttrLine().Color() = RColorNew(i+5, i+15, i+25);

      printf("Afetr setting color color %s\n", line->AttrLine().Color().AsSVG().c_str());

   }

   // drawing of RLineNew not implemented, but attributes can be seen in JSON like:
   // of course, idea to have it much compact in JSON. For instance, I could "equipt"

/*
  "fAttr" : {
        "_typename" : "ROOT::Experimental::RDrawableAttributes",
        "fContIO" : {
          "_typename" : "ROOT::Experimental::RDrawableAttributes::Record_t",
          "user_class" : "",
          "map" : {"_typename": "unordered_map<string,ROOT::Experimental::RDrawableAttributes::Value_t*>", "line_width": {
            "_typename" : "ROOT::Experimental::RDrawableAttributes::DoubleValue_t",
            "v" : 2
          }}
        }
      }
 */

   canvas->Show();
}
<commit_msg>[rdrawable] provide example using new RLine implementation<commit_after>/// \file
/// \ingroup tutorial_v7
///
/// \macro_code
///
/// \date 2018-03-18
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!
/// \author Iliana Betsou

#include "ROOT/RCanvas.hxx"
#include "ROOT/RColor.hxx"
#include "ROOT/RText.hxx"
#include "ROOT/RLine.hxx"
#include "ROOT/RPadPos.hxx"
#include <string>

void lineWidthNew()
{
   using namespace ROOT::Experimental;

   auto canvas = RCanvas::Create("Canvas Title");
   double num = 0.3;

   auto style = std::make_shared<RStyleNew>();

   style->AddBlock("line").AddInt("line_style", 2).AddString("line_color_rgb", "4,5,6");

   for (int i=10; i>0; i--){
      num = num + 0.05;

      // current way to draw primitives - it always returns drawing options
      RPadPos pt(.3_normal, RPadLength::Normal(num));
      auto optts = canvas->Draw(RText(pt, std::to_string(i)));
      optts->SetSize(13).SetAlign(32).SetFont(52);

      RPadPosNew pl1(RPadLengthNew::Normal(0.32), RPadLengthNew::Normal(num));
      RPadPosNew pl2(RPadLengthNew::Normal(0.8), RPadLengthNew::Normal(num));

      printf("pl1  horiz %f vert %f\n", pl1.Horiz().GetNormal(),  pl1.Vert().GetNormal());

      // new way of drawing - return drawable itself, which has all kind attributes
      auto line = canvas->DrawNew<RLineNew>(pl1, pl2);

      printf("line.P1  horiz %f vert %f\n", line->GetP1().Horiz().GetNormal(),  line->GetP1().Vert().GetNormal());

      // change line width
      line->AttrLine().SetWidth(i);

      printf("Current line width %f\n", line->AttrLine().GetWidth());

      // copy attributes
      auto attr = line->AttrLine();

      printf("Attribute line width %f\n", attr.GetWidth());

      // change attributes
      attr.SetWidth(i+1);

      line->AttrLine().Copy(attr);

      printf("Now line width %f\n", line->AttrLine().GetWidth());

      // assign style object to the attribute - now "Visitor" can use style as well
      line->AttrLine().UseStyle(style);

      printf("Afetr applying RStyle: width %f style %d color %s\n", line->AttrLine().GetWidth(), line->AttrLine().GetStyle(), line->AttrLine().Color().AsSVG().c_str());

      line->AttrLine().Color() = RColorNew(i+5, i+15, i+25);

      printf("Afetr setting color color %s\n", line->AttrLine().Color().AsSVG().c_str());

      auto col = line->AttrLine().Color();

      printf("Extracting color %s has alfa %s\n", col.AsSVG().c_str(), col.HasAlfa() ? "true" : "false");

   }

   // drawing of RLineNew not implemented, but attributes can be seen in JSON like:
   // of course, idea to have it much compact in JSON. For instance, I could "equipt"

/*
  "fAttr" : {
        "_typename" : "ROOT::Experimental::RDrawableAttributes",
        "fContIO" : {
          "_typename" : "ROOT::Experimental::RDrawableAttributes::Record_t",
          "user_class" : "",
          "map" : {"_typename": "unordered_map<string,ROOT::Experimental::RDrawableAttributes::Value_t*>", "line_width": {
            "_typename" : "ROOT::Experimental::RDrawableAttributes::DoubleValue_t",
            "v" : 2
          }}
        }
      }
 */

   canvas->Show();
}
<|endoftext|>


<commit_before>#include "controller.h"

Controller::Controller() {
}

int Controller::setup_db() {
	return this->tagdb.open();
}

int Controller::setup_reader() {
	return this->rfreader.init_spi();
}

void Controller::main_loop() {
	uint8_t status;

	while(1)
	{
		status = this->rfreader.read_tag();
		// status = TAG_OK;
		if (status == TAG_OK) {
			std::string mytag = this->rfreader.get_tag_str();
			printf("tag(%i): %s\n", status, mytag.c_str());
			this->tagdb.add_new(mytag);
			std::string playfile = this->tagdb.get_playfile(mytag);
			printf("playfile: %s\n", playfile.c_str());
		}
		this->rfreader.halt();
		usleep(200000);
	}
}

void Controller::close() {
	this->tagdb.close();
}

std::string Controller::get_db_error() {
	return this->tagdb.get_error();
}

<commit_msg>Controller: minor changes<commit_after>#include "controller.h"

Controller::Controller() {
}

int Controller::setup_db() {
	return this->tagdb.open();
}

int Controller::setup_reader() {
	return this->rfreader.init_spi();
}

void Controller::main_loop() {
	uint8_t status;

	while(1)
	{
		status = this->rfreader.read_tag();
		// status = TAG_OK;
		if (status == TAG_OK) {
			std::string mytag = this->rfreader.get_tag_str();
			printf("tag: %s\n", mytag.c_str());
			this->tagdb.add_new(mytag);
			tag_t mytag_info = this->tagdb.get_taginfo(mytag);
			printf("playfile: %s\n", mytag_info.playfile.c_str());
		}
		this->rfreader.halt();
		usleep(200000);
	}
}

void Controller::close() {
	this->tagdb.close();
}

std::string Controller::get_db_error() {
	return this->tagdb.get_error();
}

<|endoftext|>


<commit_before>// @(#)root/minuit2:$Id$
// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
 *                                                                    *
 **********************************************************************/

#include "Minuit2/ModularFunctionMinimizer.h"
#include "Minuit2/MinimumSeedGenerator.h"
#include "Minuit2/AnalyticalGradientCalculator.h"
#include "Minuit2/Numerical2PGradientCalculator.h"
#include "Minuit2/MinimumBuilder.h"
#include "Minuit2/MinimumSeed.h"
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnUserParameterState.h"
#include "Minuit2/MnUserParameters.h"
#include "Minuit2/MnUserCovariance.h"
#include "Minuit2/MnUserTransformation.h"
#include "Minuit2/MnUserFcn.h"
#include "Minuit2/FCNBase.h"
#include "Minuit2/FCNGradientBase.h"
#include "Minuit2/MnStrategy.h"
#include "Minuit2/MnHesse.h"
#include "Minuit2/MnLineSearch.h"
#include "Minuit2/MnParabolaPoint.h"
#include "Minuit2/MnPrint.h"

namespace ROOT {

namespace Minuit2 {

// #include "Minuit2/MnUserParametersPrint.h"

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const std::vector<double> &par,
                                                   const std::vector<double> &err, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase and std::vector of double's for parameter values and errors (step sizes)
   MnUserParameterState st(par, err);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const std::vector<double> &par,
                                                   const std::vector<double> &err, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)
   // and std::vector of double's for parameter values and errors (step sizes)
   MnUserParameterState st(par, err);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

// move nrow before cov to avoid ambiguities when using default parameters
FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const std::vector<double> &par,
                                                   unsigned int nrow, const std::vector<double> &cov, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase using std::vector for parameter error and
   // an std::vector of size n*(n+1)/2 for the covariance matrix  and n (rank of cov matrix)

   MnUserParameterState st(par, cov, nrow);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const std::vector<double> &par,
                                                   unsigned int nrow, const std::vector<double> &cov, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)
   // using std::vector for parameter error and
   // an std::vector of size n*(n+1)/2 for the covariance matrix  and n (rank of cov matrix)

   MnUserParameterState st(par, cov, nrow);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameters &upar,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase and MnUserParameters object

   MnUserParameterState st(upar);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameters &upar,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)  and MnUserParameters object

   MnUserParameterState st(upar);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameters &upar,
                                                   const MnUserCovariance &cov, const MnStrategy &strategy,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase and MnUserParameters and MnUserCovariance objects

   MnUserParameterState st(upar, cov);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameters &upar,
                                                   const MnUserCovariance &cov, const MnStrategy &strategy,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)  and
   // MnUserParameters MnUserCovariance objects

   MnUserParameterState st(upar, cov);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameterState &st,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from a FCNBase and a MnUserparameterState - interface used by all the previous ones
   // based on FCNBase. Create in this case a NumericalGradient calculator
   // Create the minuit FCN wrapper (MnUserFcn) containing the trasformation (int<->ext)

   // neeed MnUsserFcn for difference int-ext parameters
   MnUserFcn mfcn(fcn, st.Trafo());
   Numerical2PGradientCalculator gc(mfcn, st.Trafo(), strategy);

   unsigned int npar = st.VariableParameters();
   if (maxfcn == 0)
      maxfcn = 200 + 100 * npar + 5 * npar * npar;
   MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy);

   return Minimize(mfcn, gc, mnseeds, strategy, maxfcn, toler);
}

// use Gradient here
FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameterState &st,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from a FCNGradientBase and a MnUserparameterState - interface used by all the previous ones
   // based on FCNGradientBase.
   // Create in this acase an AnalyticalGradient calculator
   // Create the minuit FCN wrapper (MnUserFcn) containing the trasformation (int<->ext)

   MnUserFcn mfcn(fcn, st.Trafo());
   AnalyticalGradientCalculator gc(fcn, st.Trafo());

   unsigned int npar = st.VariableParameters();
   if (maxfcn == 0)
      maxfcn = 200 + 100 * npar + 5 * npar * npar;

   MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy);

   return Minimize(mfcn, gc, mnseeds, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const MnFcn &mfcn, const GradientCalculator &gc,
                                                   const MinimumSeed &seed, const MnStrategy &strategy,
                                                   unsigned int maxfcn, double toler) const
{
   // Interface used by all the others for the minimization using the base MinimumBuilder class
   // According to the contained type of MinimumBuilder the right type will be used

   MnPrint print("ModularFunctionMinimizer");

   const MinimumBuilder &mb = Builder();
   // std::cout << typeid(&mb).Name() << std::endl;
   double effective_toler = toler * mfcn.Up(); // scale tolerance with Up()
   // avoid tolerance too smalls (than limits)
   double eps = MnMachinePrecision().Eps2();
   if (effective_toler < eps)
      effective_toler = eps;

   // check if maxfcn is already exhausted
   // case already reached call limit
   if (mfcn.NumOfCalls() >= maxfcn) {
      print.Warn("Stop before iterating - call limit already exceeded");

      return FunctionMinimum(seed, std::vector<MinimumState>(1, seed.State()), mfcn.Up(),
                             FunctionMinimum::MnReachedCallLimit());
   }

   return mb.Minimum(mfcn, gc, seed, strategy, maxfcn, effective_toler);
}

} // namespace Minuit2

} // namespace ROOT
<commit_msg>When using externalGradient use still Numerical gradient as input to SeedGenerator<commit_after>// @(#)root/minuit2:$Id$
// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
 *                                                                    *
 **********************************************************************/

#include "Minuit2/ModularFunctionMinimizer.h"
#include "Minuit2/MinimumSeedGenerator.h"
#include "Minuit2/AnalyticalGradientCalculator.h"
#include "Minuit2/Numerical2PGradientCalculator.h"
#include "Minuit2/MinimumBuilder.h"
#include "Minuit2/MinimumSeed.h"
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnUserParameterState.h"
#include "Minuit2/MnUserParameters.h"
#include "Minuit2/MnUserCovariance.h"
#include "Minuit2/MnUserTransformation.h"
#include "Minuit2/MnUserFcn.h"
#include "Minuit2/FCNBase.h"
#include "Minuit2/FCNGradientBase.h"
#include "Minuit2/MnStrategy.h"
#include "Minuit2/MnHesse.h"
#include "Minuit2/MnLineSearch.h"
#include "Minuit2/MnParabolaPoint.h"
#include "Minuit2/MnPrint.h"

namespace ROOT {

namespace Minuit2 {

// #include "Minuit2/MnUserParametersPrint.h"

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const std::vector<double> &par,
                                                   const std::vector<double> &err, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase and std::vector of double's for parameter values and errors (step sizes)
   MnUserParameterState st(par, err);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const std::vector<double> &par,
                                                   const std::vector<double> &err, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)
   // and std::vector of double's for parameter values and errors (step sizes)
   MnUserParameterState st(par, err);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

// move nrow before cov to avoid ambiguities when using default parameters
FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const std::vector<double> &par,
                                                   unsigned int nrow, const std::vector<double> &cov, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase using std::vector for parameter error and
   // an std::vector of size n*(n+1)/2 for the covariance matrix  and n (rank of cov matrix)

   MnUserParameterState st(par, cov, nrow);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const std::vector<double> &par,
                                                   unsigned int nrow, const std::vector<double> &cov, unsigned int stra,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)
   // using std::vector for parameter error and
   // an std::vector of size n*(n+1)/2 for the covariance matrix  and n (rank of cov matrix)

   MnUserParameterState st(par, cov, nrow);
   MnStrategy strategy(stra);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameters &upar,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase and MnUserParameters object

   MnUserParameterState st(upar);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameters &upar,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)  and MnUserParameters object

   MnUserParameterState st(upar);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameters &upar,
                                                   const MnUserCovariance &cov, const MnStrategy &strategy,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNBase and MnUserParameters and MnUserCovariance objects

   MnUserParameterState st(upar, cov);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameters &upar,
                                                   const MnUserCovariance &cov, const MnStrategy &strategy,
                                                   unsigned int maxfcn, double toler) const
{
   // minimize from FCNGradientBase (use analytical gradient provided in FCN)  and
   // MnUserParameters MnUserCovariance objects

   MnUserParameterState st(upar, cov);
   return Minimize(fcn, st, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameterState &st,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from a FCNBase and a MnUserparameterState - interface used by all the previous ones
   // based on FCNBase. Create in this case a NumericalGradient calculator
   // Create the minuit FCN wrapper (MnUserFcn) containing the trasformation (int<->ext)

   // neeed MnUsserFcn for difference int-ext parameters
   MnUserFcn mfcn(fcn, st.Trafo());
   Numerical2PGradientCalculator gc(mfcn, st.Trafo(), strategy);

   unsigned int npar = st.VariableParameters();
   if (maxfcn == 0)
      maxfcn = 200 + 100 * npar + 5 * npar * npar;
   MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy);

   return Minimize(mfcn, gc, mnseeds, strategy, maxfcn, toler);
}

// use Gradient here
FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameterState &st,
                                                   const MnStrategy &strategy, unsigned int maxfcn, double toler) const
{
   // minimize from a FCNGradientBase and a MnUserparameterState - interface used by all the previous ones
   // based on FCNGradientBase.
   // Create in this acase an AnalyticalGradient calculator
   // Create the minuit FCN wrapper (MnUserFcn) containing the trasformation (int<->ext)

   MnUserFcn mfcn(fcn, st.Trafo());
   AnalyticalGradientCalculator gc(fcn, st.Trafo());

   unsigned int npar = st.VariableParameters();
   if (maxfcn == 0)
      maxfcn = 200 + 100 * npar + 5 * npar * npar;

   // use numerical gradient to compute initial derivatives for SeedGenerator
   Numerical2PGradientCalculator numgc(mfcn, st.Trafo(), strategy);
   MinimumSeed mnseeds = SeedGenerator()(mfcn, numgc, st, strategy);

   return Minimize(mfcn, gc, mnseeds, strategy, maxfcn, toler);
}

FunctionMinimum ModularFunctionMinimizer::Minimize(const MnFcn &mfcn, const GradientCalculator &gc,
                                                   const MinimumSeed &seed, const MnStrategy &strategy,
                                                   unsigned int maxfcn, double toler) const
{
   // Interface used by all the others for the minimization using the base MinimumBuilder class
   // According to the contained type of MinimumBuilder the right type will be used

   MnPrint print("ModularFunctionMinimizer");

   const MinimumBuilder &mb = Builder();
   // std::cout << typeid(&mb).Name() << std::endl;
   double effective_toler = toler * mfcn.Up(); // scale tolerance with Up()
   // avoid tolerance too smalls (than limits)
   double eps = MnMachinePrecision().Eps2();
   if (effective_toler < eps)
      effective_toler = eps;

   // check if maxfcn is already exhausted
   // case already reached call limit
   if (mfcn.NumOfCalls() >= maxfcn) {
      print.Warn("Stop before iterating - call limit already exceeded");

      return FunctionMinimum(seed, std::vector<MinimumState>(1, seed.State()), mfcn.Up(),
                             FunctionMinimum::MnReachedCallLimit());
   }

   return mb.Minimum(mfcn, gc, seed, strategy, maxfcn, effective_toler);
}

} // namespace Minuit2

} // namespace ROOT
<|endoftext|>


<commit_before>#include "cellmlmodelrepositorywindow.h"
#include "internetfile.h"

#include "ui_cellmlmodelrepositorywindow.h"

#include <QDebug>

namespace OpenCOR {
namespace CellMLModelRepository {

CellmlModelRepositoryWindow::CellmlModelRepositoryWindow(QWidget *pParent) :
    DockWidget(pParent),
    mUi(new Ui::CellmlModelRepositoryWindow)
{
    // Set up the UI

    mUi->setupUi(this);

    // Retrieve the list of models in the CellML Model Repository as JSON code
    // from http://50.18.64.32/workspace/res/contents.json

    Core::InternetFile internetFile;

    QNetworkReply *res = internetFile.get("http://50.18.64.32/workspace/rest/contents.json");

    qDebug(QString(res->readAll()).toLatin1().constData());
}

CellmlModelRepositoryWindow::~CellmlModelRepositoryWindow()
{
    // Delete the UI

    delete mUi;
}

void CellmlModelRepositoryWindow::retranslateUi()
{
    // Retranslate the whole window

    mUi->retranslateUi(this);
}

} }
<commit_msg>Very minor fix (was getting a warning on Linux and Mac OS X).<commit_after>#include "cellmlmodelrepositorywindow.h"
#include "internetfile.h"

#include "ui_cellmlmodelrepositorywindow.h"

#include <QDebug>

namespace OpenCOR {
namespace CellMLModelRepository {

CellmlModelRepositoryWindow::CellmlModelRepositoryWindow(QWidget *pParent) :
    DockWidget(pParent),
    mUi(new Ui::CellmlModelRepositoryWindow)
{
    // Set up the UI

    mUi->setupUi(this);

    // Retrieve the list of models in the CellML Model Repository as JSON code
    // from http://50.18.64.32/workspace/res/contents.json

    Core::InternetFile internetFile;

    QNetworkReply *res = internetFile.get("http://50.18.64.32/workspace/rest/contents.json");

    qDebug("%s", QString(res->readAll()).toLatin1().constData());
}

CellmlModelRepositoryWindow::~CellmlModelRepositoryWindow()
{
    // Delete the UI

    delete mUi;
}

void CellmlModelRepositoryWindow::retranslateUi()
{
    // Retranslate the whole window

    mUi->retranslateUi(this);
}

} }
<|endoftext|>


<commit_before>template<typename Key, typename Val>
struct deamortized_map {
  deamortized_map();
  struct Cell {
    Key key;
    Value val;
  };
  Node {
    Cell data;
    Node *left, *right, *next;
    size_t height;
  };

  Node * head;
  Cell * find(const Key&) const;
  Cell * insert(const Key&, const Val&);
  size_t size;
};

template<typename Key, typename Val>
struct insert_ans {
  bool success;
  typename deamortized_map<Key,Val>::Node *here, *ans;
}

template<typename Key, typename Val>
insert_ans<Key,Val> node_insert(typename deamortized_map<Key,Val>::Node * root, const Key& key, const Val& val) {
  if (root->right && root->right->right && root->right->right->height == root->height) {
    typename deamortized_map<Key,Val>::Node * new_root = root->right;
    root->right = new_root->left;
    new_root->left = root;
    new_root->height += 1;
    return node_insert(new_root, key, val);
  }
  if (root) {
    if (key == root->key) return {false, root, root};
    if (key < root->key) return node_insert
  }
}

// TODO: sentinel

template<typename Key, typename Val>
std::pair<bool,Node *> node_insert(typename deamortized_map<Key,Val>::Node * root, const Key& key, const Val& val) {
  if (not root) {
    auto * ans = new typename deamortized_map<Key,Val>::Node();
    ans->data->key = key;
    ans->left = ans->right = ans->next = nullptr;
    ans->height = 0;
    return std::make_pair(true, ans);
  }
  if (key == root->data->key) {
    return std::make_pair(false, root);
  }
  if (key < root->data->key) {
    if (left_heavy(root)) { root = rotate_right(root); }
    root->left = node_insert(root->left, key, val).second;
    reheight(root);
    return root;
  }

}

template<typename Key, typename Val>
typename deamortized_map<Key,Val>::Node * rotate_right(typename deamortized_map<Key,Val>::Node * root) {
  // single rotation:
  if ((not root->left->left) or (not root->left->right) or (root->left->left->height >= root->left->right->height)) {
    typename deamortized_map<Key,Val>::Node * const ans = root->left;
    root->left = ans->right;
    ans->right = root;
    reheight(root);
    reheight(ans);
    return ans;
  } else { // double rotation
    typename deamortized_map<Key,Val>::Node * const ans = root->left->right;
    root->left->right = ans->left;
    ans->left = root->left;
    root->left = ans->right;
    ans->right = root;
    reheight(ans->left);
    reheight(ans->right);
    reheight(ans);
    return ans;
  }
}
<commit_msg>Switch to AA trees for deamortized map<commit_after>#include <cstddef>
#include <utility>
#include <cstdlib>

template<typename Key, typename Val>
struct deamortized_map {
  struct Node {
    Key key;
    Val val;
    Node *left, *right; // tree structure
    Node *prev, *next; // for iterating
    std::size_t level; // for balance
    Node(const Key& key, const Val& val)
      : key(key), val(val),
	left(bottom()), right(bottom()), prev(NULL), next(NULL), level(1) {}
  };

  // AA trees:
  static Node * skew(Node * root) {
    if (root->left->level == root->level) {
      // rotate right
      Node * ans = root->left;
      root->left = ans->right;
      ans->right = root;
      return ans;
    }
    return root;
  }

  static Node * split(Node * root) {
    if (root->right->right->level == root->level) {
      //rotate left
      Node * ans = root->right;
      root->right = ans->left;
      ans->left = root;
      ans->level += 1;
      return ans;
    }
    return root;
  }

  struct InsertAns {
    bool is_new;
    Node * location;
    Node * new_root;
  };

  static InsertAns insert(const Key& key, const Val& val, Node * root) {
    if (0 == root->level) {
      InsertAns ans;
      // link up node later
      ans.location = new Node(key, val);
      ans.new_root = ans.location;
      ans.is_new = true;
      return ans;
    }
    InsertAns ans;
    if (key < root->key) ans = insert(key, val, root->left);
    else if (key < root->key) ans = insert(key, val, root->right);
    else {
      ans.is_new = false;
      ans.location = root;
      ans.new_root = root;
    }
    if (ans.is_new) {
      ans.new_root = skew(ans.new_root);
      ans.new_root = split(ans.new_root);
    }
    return ans;
  }

  static Node * find(const Key& key, const Node* const root) {
    if (0 == root->level) return NULL;
    if (key <= root->key) return root;
    if (key < root->key) return find(key, root->left);
    return find(key, root->right);
  }

  Node *head, *root;
  std::size_t size;
  deamortized_map() : head(NULL), root(bottom()), size(0) {}
  Node * find(const Key& key) const {
    return find(key, root);
  }
  std::pair<bool,Node*> insert(const Key& key, const Val& val) {
    InsertAns ia = insert(key, val, root);
    if (ia.is_new) {
      ia.location->next = head;
      ia.location->prev = NULL;
      head = ia.location;
      root = ia.new_root;
      ++size;
    }
    return make_pair(ia.is_new, ia.location);
  }

  static const Node * bottom() {
    static Node * ans = NULL;
    if (NULL == ans) {
      ans = malloc(sizeof(Node));
      ans->left = ans->right = ans;
      ans->prev = ans->next = NULL;
      ans->level = 0;
    }
    return ans;
  }
};
<|endoftext|>


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

#ifndef _SAL_I18N_INPUTMETHOD_HXX
#define _SAL_I18N_INPUTMETHOD_HXX

#ifndef _VCL_DLLAPI_H
#include "dllapi.h"
#endif

extern "C" char* GetMethodName( XIMStyle nStyle, char *pBuf, int nBufSize);

#define bUseInputMethodDefault True

class VCL_DLLPUBLIC SalI18N_InputMethod
{
    Bool        mbUseable;  // system supports locale as well as status
                            // and preedit style ?
    Bool        mbMultiLingual; // system supports iiimp
    XIM         maMethod;
    XIMCallback maDestroyCallback;
    XIMStyles  *mpStyles;

public:

    Bool        IsMultiLingual()        { return mbMultiLingual;    }
    Bool        PosixLocale();
    Bool        UseMethod()             { return mbUseable; }
    XIM         GetMethod()             { return maMethod;  }
    void        HandleDestroyIM();
    Bool        CreateMethod( Display *pDisplay );
    XIMStyles  *GetSupportedStyles()    { return mpStyles;  }
    Bool        SetLocale( const char* pLocale = "" );
    Bool        FilterEvent( XEvent *pEvent, XLIB_Window window );
    Bool        AddConnectionWatch (Display *pDisplay, void *pConnectionHandler);

    #ifdef _USE_PRINT_EXTENSION_
    void            Invalidate()                    { mbUseable = False; }
    #endif

    SalI18N_InputMethod();
    ~SalI18N_InputMethod();
};

#endif // _SAL_I18N_INPUTMETHOD_HXX

<commit_msg>INTEGRATION: CWS vgbugs07 (1.13.606); FILE MERGED 2007/06/04 13:29:56 vg 1.13.606.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: i18n_im.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 20:39:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SAL_I18N_INPUTMETHOD_HXX
#define _SAL_I18N_INPUTMETHOD_HXX

#ifndef _VCL_DLLAPI_H
#include <vcl/dllapi.h>
#endif

extern "C" char* GetMethodName( XIMStyle nStyle, char *pBuf, int nBufSize);

#define bUseInputMethodDefault True

class VCL_DLLPUBLIC SalI18N_InputMethod
{
    Bool        mbUseable;  // system supports locale as well as status
                            // and preedit style ?
    Bool        mbMultiLingual; // system supports iiimp
    XIM         maMethod;
    XIMCallback maDestroyCallback;
    XIMStyles  *mpStyles;

public:

    Bool        IsMultiLingual()        { return mbMultiLingual;    }
    Bool        PosixLocale();
    Bool        UseMethod()             { return mbUseable; }
    XIM         GetMethod()             { return maMethod;  }
    void        HandleDestroyIM();
    Bool        CreateMethod( Display *pDisplay );
    XIMStyles  *GetSupportedStyles()    { return mpStyles;  }
    Bool        SetLocale( const char* pLocale = "" );
    Bool        FilterEvent( XEvent *pEvent, XLIB_Window window );
    Bool        AddConnectionWatch (Display *pDisplay, void *pConnectionHandler);

    #ifdef _USE_PRINT_EXTENSION_
    void            Invalidate()                    { mbUseable = False; }
    #endif

    SalI18N_InputMethod();
    ~SalI18N_InputMethod();
};

#endif // _SAL_I18N_INPUTMETHOD_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: saldata.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_SALDATA_HXX
#define _SV_SALDATA_HXX

// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include <signal.h>

#ifndef _SALSTD_HXX
#include <salstd.hxx>
#endif
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _SV_SALWTYPE_HXX
#include <salwtype.hxx>
#endif

// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class SalXLib;
class SalDisplay;
class SalInstance;
class SalFrame;
class SalPrinter;

// -=-= typedefs -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef SIG_PF
typedef void SIG_FUNC_TYP(int);
typedef SIG_FUNC_TYP *SIG_TYP;
#define SIG_PF SIG_TYP
#endif

DECLARE_LIST( SalDisplays, SalDisplay* )

#if defined SCO || defined LINUX || defined NETBSD || defined AIX || defined HPUX || defined FREEBSD
#include <pthread.h>
#else
typedef unsigned int pthread_t;
#endif

// -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class SalData
{
            char**              argv_;
            int                 argc_;
            String              aBinaryPath_;

            SALTIMERPROC        pTimerProc_;        // timer callback proc

            SIG_TYP             sig_[30];
            BOOL                bNoExceptions_;

            SalXLib            *pXLib_;

            SalDisplays         SalDisplays_;
            SalDisplay         *pDefDisp_;
            SalDisplay         *pCurDisp_;

            pthread_t           hMainThread_;
public:
            SalInstance        *pFirstInstance_;    // pointer of first instance
            SalFrame           *pFirstFrame_;       // pointer of first frame

public:
                                SalData();
                                ~SalData();

            void                Init( int *pArgc, char *ppArgv[] );

    inline  const XubString    &GetFileName() const { return aBinaryPath_; }
    inline  USHORT              GetCommandLineParamCount() const
                                    { return argc_; }
            XubString           GetCommandLineParam( USHORT nParam ) const;

            long                ShutDown() const;
            long                Close() const;
    inline  void                XError( Display     *pDisplay,
                                        XErrorEvent *pEvent ) const;

            SalDisplay         *GetDisplay( Display *pDisplay );
    inline  SalDisplay         *GetDisplay( long nDisplay ) const
                                    { return SalDisplays_.GetObject(nDisplay); }
    inline  SalDisplay         *GetDefDisp() const { return pDefDisp_; }
    inline  SalDisplay         *GetCurDisp() const { return pCurDisp_; }
    inline  void                SetDefDisp( SalDisplay *pDisp )
                                    { pDefDisp_ = pDisp; }
    inline  void                SetCurDisp( SalDisplay *pDisp )
                                    { pCurDisp_ = pDisp; }
    inline  void                Insert( SalDisplay *pDisplay );
    inline  void                Remove( SalDisplay *pDisplay );

    inline  SalXLib            *GetLib() const { return pXLib_; }
    inline  pthread_t       GetMainThread() const { return hMainThread_; }

            void                StartTimer( ULONG nMS );
    inline  void                StopTimer();
    inline  void                SetCallback( SALTIMERPROC pProc )
                                    { pTimerProc_ = pProc; }
            void                Timeout() const;

};

// -=-= inlines =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
inline void SetSalData( SalData* pData )
{ ImplGetSVData()->mpSalData = (void*)pData; }

inline SalData* GetSalData()
{ return (SalData*)ImplGetSVData()->mpSalData; }

inline void SalData::Insert( SalDisplay *pDisplay )
{ SalDisplays_.Insert( pDisplay ); }

inline void SalData::Remove( SalDisplay *pDisplay )
{ SalDisplays_.Remove( pDisplay ); }

#ifdef _SV_SALDISP_HXX
inline void SalData::XError( Display *pDisplay, XErrorEvent *pEvent ) const
{ pXLib_->XError( pDisplay, pEvent ); }
#endif
#endif // _SV_SALDATA_HXX

<commit_msg>MutexReleaser moved here<commit_after>/*************************************************************************
 *
 *  $RCSfile: saldata.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obr $ $Date: 2001-02-09 14:46:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_SALDATA_HXX
#define _SV_SALDATA_HXX

// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include <signal.h>

#ifndef _SALSTD_HXX
#include <salstd.hxx>
#endif
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _SV_SALWTYPE_HXX
#include <salwtype.hxx>
#endif
#ifndef _SV_SALINST_HXX
#include <salinst.hxx>
#endif

// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class SalXLib;
class SalDisplay;
class SalInstance;
class SalFrame;
class SalPrinter;

// -=-= typedefs -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef SIG_PF
typedef void SIG_FUNC_TYP(int);
typedef SIG_FUNC_TYP *SIG_TYP;
#define SIG_PF SIG_TYP
#endif

DECLARE_LIST( SalDisplays, SalDisplay* )

#if defined SCO || defined LINUX || defined NETBSD || defined AIX || defined HPUX || defined FREEBSD
#include <pthread.h>
#else
typedef unsigned int pthread_t;
#endif

// -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class SalData
{
            char**              argv_;
            int                 argc_;
            String              aBinaryPath_;

            SALTIMERPROC        pTimerProc_;        // timer callback proc

            SIG_TYP             sig_[30];
            BOOL                bNoExceptions_;

            SalXLib            *pXLib_;

            SalDisplays         SalDisplays_;
            SalDisplay         *pDefDisp_;
            SalDisplay         *pCurDisp_;

            pthread_t           hMainThread_;
public:
            SalInstance        *pFirstInstance_;    // pointer of first instance
            SalFrame           *pFirstFrame_;       // pointer of first frame

public:
                                SalData();
                                ~SalData();

            void                Init( int *pArgc, char *ppArgv[] );

    inline  const XubString    &GetFileName() const { return aBinaryPath_; }
    inline  USHORT              GetCommandLineParamCount() const
                                    { return argc_; }
            XubString           GetCommandLineParam( USHORT nParam ) const;

            long                ShutDown() const;
            long                Close() const;
    inline  void                XError( Display     *pDisplay,
                                        XErrorEvent *pEvent ) const;

            SalDisplay         *GetDisplay( Display *pDisplay );
    inline  SalDisplay         *GetDisplay( long nDisplay ) const
                                    { return SalDisplays_.GetObject(nDisplay); }
    inline  SalDisplay         *GetDefDisp() const { return pDefDisp_; }
    inline  SalDisplay         *GetCurDisp() const { return pCurDisp_; }
    inline  void                SetDefDisp( SalDisplay *pDisp )
                                    { pDefDisp_ = pDisp; }
    inline  void                SetCurDisp( SalDisplay *pDisp )
                                    { pCurDisp_ = pDisp; }
    inline  void                Insert( SalDisplay *pDisplay );
    inline  void                Remove( SalDisplay *pDisplay );

    inline  SalXLib            *GetLib() const { return pXLib_; }
    inline  pthread_t       GetMainThread() const { return hMainThread_; }

            void                StartTimer( ULONG nMS );
    inline  void                StopTimer();
    inline  void                SetCallback( SALTIMERPROC pProc )
                                    { pTimerProc_ = pProc; }
            void                Timeout() const;

};

// -=-= inlines =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
inline void SetSalData( SalData* pData )
{ ImplGetSVData()->mpSalData = (void*)pData; }

inline SalData* GetSalData()
{ return (SalData*)ImplGetSVData()->mpSalData; }

inline void SalData::Insert( SalDisplay *pDisplay )
{ SalDisplays_.Insert( pDisplay ); }

inline void SalData::Remove( SalDisplay *pDisplay )
{ SalDisplays_.Remove( pDisplay ); }

#ifdef _SV_SALDISP_HXX
inline void SalData::XError( Display *pDisplay, XErrorEvent *pEvent ) const
{ pXLib_->XError( pDisplay, pEvent ); }
#endif

class YieldMutexReleaser
{
    ULONG               m_nYieldCount;
    SalYieldMutex*      m_pSalInstYieldMutex;
public:
    inline YieldMutexReleaser();
    inline ~YieldMutexReleaser();
};

inline YieldMutexReleaser::YieldMutexReleaser()
{
    SalData *pSalData       = GetSalData();
    m_pSalInstYieldMutex    =
        pSalData->pFirstInstance_->maInstData.mpSalYieldMutex;

    ULONG i;
    if ( m_pSalInstYieldMutex->GetThreadId() ==
         NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
    {
        m_nYieldCount = m_pSalInstYieldMutex->GetAcquireCount();
        for ( i = 0; i < m_nYieldCount; i++ )
            m_pSalInstYieldMutex->release();
    }
    else
        m_nYieldCount = 0;
}

inline YieldMutexReleaser::~YieldMutexReleaser()
{
    // Yield-Semaphore wieder holen
    while ( m_nYieldCount )
    {
        m_pSalInstYieldMutex->acquire();
        m_nYieldCount--;
    }
}

#endif // _SV_SALDATA_HXX

<|endoftext|>