text:
#ifndef BOOST_LEAF_EXCEPTION_HPP_INCLUDED
#define BOOST_LEAF_EXCEPTION_HPP_INCLUDED

// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.

// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_LEAF_ENABLE_WARNINGS
#   if defined(__clang__)
#       pragma clang system_header
#   elif (__GNUC__*100+__GNUC_MINOR__>301)
#       pragma GCC system_header
#   elif defined(_MSC_VER)
#       pragma warning(push,1)
#   endif
#endif

#include <boost/leaf/error.hpp>
#include <exception>

#define BOOST_LEAF_EXCEPTION ::boost::leaf::leaf_detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
#define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception

////////////////////////////////////////

namespace boost { namespace leaf {

    namespace leaf_detail
    {
        struct throw_with_loc
        {
            char const * const file;
            int const line;
            char const * const fn;

            template <class Ex>
            [[noreturn]] friend void operator+( throw_with_loc loc, Ex const & ex )
            {
                ex.load_source_location_(loc.file, loc.line, loc.fn);
                ::boost::leaf::throw_exception(ex);
            }
        };
    }

} }

////////////////////////////////////////

namespace boost { namespace leaf {

    namespace leaf_detail
    {
        inline void enforce_std_exception( std::exception const & ) noexcept { }

        class exception_base
        {
            std::shared_ptr<void const> auto_id_bump_;
        public:

            virtual error_id get_error_id() const noexcept = 0;

        protected:

            exception_base():
                auto_id_bump_(0, [](void const *) { (void) new_id(); })
            {
            }

            ~exception_base() noexcept { }
        };

        template <class Ex>
        class exception:
            public Ex,
            public exception_base,
            public error_id
        {
            error_id get_error_id() const noexcept final override
            {
                return *this;
            }

        public:

            exception( exception const & ) = default;
            exception( exception && ) = default;

            BOOST_LEAF_CONSTEXPR exception( error_id id, Ex && ex ) noexcept:
                Ex(std::move(ex)),
                error_id(id)
            {
                enforce_std_exception(*this);
            }

            explicit BOOST_LEAF_CONSTEXPR exception( error_id id ) noexcept:
                error_id(id)
            {
                enforce_std_exception(*this);
            }
        };

        template <class... T>
        struct at_least_one_derives_from_std_exception;

        template <>
        struct at_least_one_derives_from_std_exception<>: std::false_type { };

        template <class T, class... Rest>
        struct at_least_one_derives_from_std_exception<T, Rest...>
        {
            constexpr static const bool value = std::is_base_of<std::exception,T>::value || at_least_one_derives_from_std_exception<Rest...>::value;
        };
    }

    template <class Ex, class... E>
    inline
    typename std::enable_if<std::is_base_of<std::exception,Ex>::value, leaf_detail::exception<Ex>>::type
    exception( Ex && ex, E && ... e ) noexcept
    {
        static_assert(!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
        auto id = leaf::new_error(std::forward<E>(e)...);
        return leaf_detail::exception<Ex>(id, std::forward<Ex>(ex));
    }

    template <class E1, class... E>
    inline
    typename std::enable_if<!std::is_base_of<std::exception,E1>::value, leaf_detail::exception<std::exception>>::type
    exception( E1 && car, E && ... cdr ) noexcept
    {
        static_assert(!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
        auto id = leaf::new_error(std::forward<E1>(car), std::forward<E>(cdr)...);
        return leaf_detail::exception<std::exception>(id);
    }

    inline leaf_detail::exception<std::exception> exception() noexcept
    {
        return leaf_detail::exception<std::exception>(leaf::new_error());
    }

} }

#endif

max_stars_repo_name: armdevvel/boost

max_issues_repo_name: armdevvel/boost

max_forks_repo_name: armdevvel/boost


text: #include <boost/graph/named_graph.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
// -----------------------------------------------------------------------------
// Fern © Geoneric
//
// This file is part of Geoneric Fern which is available under the terms of
// the GNU General Public License (GPL), version 2. If you do not want to
// be bound by the terms of the GPL, you may purchase a proprietary license
// from Geoneric (http://www.geoneric.eu/contact).
// -----------------------------------------------------------------------------
#define BOOST_TEST_MODULE fern algorithm algebra binary_local_operation
#include <boost/test/unit_test.hpp>
#include "fern/core/data_customization_point/scalar.h"
#include "fern/core/data_customization_point/vector.h"
#include "fern/feature/core/data_customization_point/array.h"
#include "fern/feature/core/data_customization_point/masked_array.h"
#include "fern/feature/core/data_customization_point/masked_scalar.h"
#include "fern/algorithm/algebra/elementary/add.h"

namespace fa = fern::algorithm;

using ArgumentValue = int32_t;
using ResultValue = int32_t;

template<
    class Value1,
    class Value2
>
using Algorithm = fa::add::detail::Algorithm<Value1, Value2>;

template<
    class Value1,
    class Value2,
    class Result
>
using OutOfRangePolicy = fa::add::OutOfRangePolicy<Value1, Value2, Result>;

BOOST_AUTO_TEST_CASE(d0_array_d0_array)
{
    using InputNoDataPolicy = fa::InputNoDataPolicies<fa::SkipNoData,
          fa::SkipNoData>;
    using OutputNoDataPolicy = fa::DontMarkNoData;
    using Argument1 = ArgumentValue;
    using Argument2 = ArgumentValue;
    using Result = ResultValue;

    fa::ParallelExecutionPolicy parallel;
    fa::SequentialExecutionPolicy sequential;

    OutputNoDataPolicy output_no_data_policy;
    Argument1 argument1{-5};
    Argument2 argument2{-6};
    Result result{3};

    fa::binary_local_operation<
        Algorithm,
        fa::binary::DiscardDomainErrors,
        fa::binary::DiscardRangeErrors>(
            InputNoDataPolicy{{}, {}},
            output_no_data_policy,
            sequential, argument1, argument2, result);

    BOOST_CHECK_EQUAL(result, -11);

    result = 3;

    fa::binary_local_operation<
        Algorithm,
        fa::binary::DiscardDomainErrors,
        fa::binary::DiscardRangeErrors>(
            InputNoDataPolicy{{}, {}},
            output_no_data_policy,
            parallel, argument1, argument2, result);

    BOOST_CHECK_EQUAL(result, -11);
}

BOOST_AUTO_TEST_CASE(masked_d0_array_d0_array)
{
    using InputNoDataPolicy = fa::InputNoDataPolicies<
        fa::DetectNoDataByValue<bool>, fa::DetectNoDataByValue<bool>>;
    using OutputNoDataPolicy = fa::MarkNoDataByValue<bool>;
    using Argument1 = fern::MaskedScalar<ArgumentValue>;
    using Argument2 = fern::MaskedScalar<ArgumentValue>;
    using Result = fern::MaskedScalar<ResultValue>;

    fa::SequentialExecutionPolicy sequential;

    Argument1 argument1;
    Argument2 argument2;
    Result result;

    // Input is not masked.
    {
        argument1.value() = -5;
        argument1.mask() = false;
        argument2.value() = -6;
        argument2.mask() = false;
        result.value() = 3;
        result.mask() = false;

        InputNoDataPolicy input_no_data_policy{
            {argument1.mask(), true},
            {argument2.mask(), true}};
        OutputNoDataPolicy output_no_data_policy(result.mask(), true);

        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            fa::binary::DiscardRangeErrors>(
                input_no_data_policy,
                output_no_data_policy,
                sequential, argument1, argument2, result);

        BOOST_CHECK_EQUAL(result.mask(), false);
        BOOST_CHECK_EQUAL(result.value(), -11);
    }

    // Input is masked.
    {
        argument1.value() = -5;
        argument1.mask() = true;
        argument2.value() = -6;
        argument2.mask() = false;
        result.value() = 3;
        result.mask() = false;

        InputNoDataPolicy input_no_data_policy{
            {argument1.mask(), true},
            {argument2.mask(), true}};
        OutputNoDataPolicy output_no_data_policy(result.mask(), true);

        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            fa::binary::DiscardRangeErrors>(
                input_no_data_policy,
                output_no_data_policy,
                sequential, argument1, argument2, result);

        BOOST_CHECK_EQUAL(result.mask(), true);
        BOOST_CHECK_EQUAL(result.value(), 3);
    }

    // Input is out of domain.
    {
        // TODO  Use other operation.
    }

    // Result goes out of range.
    {
        argument1.value() = fern::max<ArgumentValue>();
        argument1.mask() = false;
        argument2.value() = 1;
        argument2.mask() = false;
        result.value() = 3;
        result.mask() = false;

        InputNoDataPolicy input_no_data_policy{
            {argument1.mask(), true},
            {argument2.mask(), true}};
        OutputNoDataPolicy output_no_data_policy(result.mask(), true);
        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            OutOfRangePolicy>(
                input_no_data_policy,
                output_no_data_policy,
                sequential, argument1, argument2, result);

        BOOST_CHECK_EQUAL(result.mask(), true);

        // Result value is max<ArgumentValue> + 1, which equals
        // min<ArgumentValue>.
        BOOST_CHECK_EQUAL(result.value(), fern::min<ArgumentValue>());
    }
}

BOOST_AUTO_TEST_CASE(d1_array_d0_array_sequential)
{
    using InputNoDataPolicy = fa::InputNoDataPolicies<fa::SkipNoData,
          fa::SkipNoData>;
    using OutputNoDataPolicy = fa::DontMarkNoData;

    OutputNoDataPolicy output_no_data_policy;

    fa::SequentialExecutionPolicy sequential;

    // vector
    {
        using Argument1 = std::vector<ArgumentValue>;
        using Argument2 = ArgumentValue;
        using Result = std::vector<ResultValue>;

        Argument1 argument1{-5, 0, 5};
        Argument2 argument2{6};
        Result result{3, 3, 3};

        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            fa::binary::DiscardRangeErrors>(
                InputNoDataPolicy{{}, {}},
                output_no_data_policy,
                sequential, argument1, argument2, result);

        BOOST_CHECK_EQUAL(result[0], 1);
        BOOST_CHECK_EQUAL(result[1], 6);
        BOOST_CHECK_EQUAL(result[2], 11);

        std::fill(result.begin(), result.end(), 3);

        // Switch arguments.
        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            fa::binary::DiscardRangeErrors>(
                InputNoDataPolicy{{}, {}},
                output_no_data_policy,
                sequential, argument2, argument1, result);

        BOOST_CHECK_EQUAL(result[0], 1);
        BOOST_CHECK_EQUAL(result[1], 6);
        BOOST_CHECK_EQUAL(result[2], 11);
    }

    // 1d array
    {
        using Argument1 = fern::Array<ArgumentValue, 1>;
        using Argument2 = ArgumentValue;
        using Result = fern::Array<ResultValue, 1>;

        Argument1 argument1{-5, 0, 5};
        Argument2 argument2{6};
        Result result{3, 3, 3};

        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            fa::binary::DiscardRangeErrors>(
                InputNoDataPolicy{{}, {}},
                output_no_data_policy,
                sequential, argument1, argument2, result);

        BOOST_CHECK_EQUAL(result[0], 1);
        BOOST_CHECK_EQUAL(result[1], 6);
        BOOST_CHECK_EQUAL(result[2], 11);
    }

    // empty
    {
        using Argument1 = std::vector<ArgumentValue>;
        using Argument2 = ArgumentValue;
        using Result = std::vector<ResultValue>;

        Argument1 argument1;
        Argument2 argument2{};
        Result result;

        fa::binary_local_operation<
            Algorithm,
            fa::binary::DiscardDomainErrors,
            fa::binary::DiscardRangeErrors>(
                InputNoDataPolicy{{}, {}},
                output_no_data_policy,
                sequential, argument1, argument2, result);

        BOOST_CHECK(result.empty());
    }
}

/// BOOST_AUTO_TEST_CASE(array_1d_parallel)
/// {
///     using InputNoDataPolicy = fern::SkipNoData;
///     using OutputNoDataPolicy = fern::DontMarkNoData;
///
///     OutputNoDataPolicy output_no_data_policy;
///
///     // vector
///     {
///         using Argument = std::vector<ArgumentValue>;
///         using Result = std::vector<ResultValue>;
///
///         Argument argument{-5, 0, 5};
///         Result result{3, 3, 3};
///
///         fa::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 InputNoDataPolicy(),
///                 output_no_data_policy,
///                 parallel, argument, result);
///
///         BOOST_REQUIRE_EQUAL(result[0], 5);
///         BOOST_REQUIRE_EQUAL(result[1], 0);
///         BOOST_REQUIRE_EQUAL(result[2], 5);
///     }
///
///     // 1d array
///     {
///         using Argument = fern::Array<ArgumentValue, 1>;
///         using Result = fern::Array<ResultValue, 1>;
///
///         Argument argument{-5, 0, 5};
///         Result result{3, 3, 3};
///
///         fa::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 InputNoDataPolicy(),
///                 output_no_data_policy,
///                 parallel, argument, result);
///
///         BOOST_REQUIRE_EQUAL(result[0], 5);
///         BOOST_REQUIRE_EQUAL(result[1], 0);
///         BOOST_REQUIRE_EQUAL(result[2], 5);
///     }
///
///     // empty
///     {
///         using Argument = std::vector<ArgumentValue>;
///         using Result = std::vector<ResultValue>;
///
///         Argument argument;
///         Result result;
///
///         fa::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 InputNoDataPolicy(),
///                 output_no_data_policy,
///                 parallel, argument, result);
///
///         BOOST_CHECK(result.empty());
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(array_1d_masked)
/// {
///     using Argument = fern::MaskedArray<ArgumentValue, 1>;
///     using Result = fern::MaskedArray<ResultValue, 1>;
///     using InputNoDataPolicy = fern::DetectNoDataByValue<fern::Mask<1>>;
///     using OutputNoDataPolicy = fern::MarkNoDataByValue<fern::Mask<1>>;
///
///     {
///         Argument argument{-5, 0, 5};
///         Result result(3);
///
///         InputNoDataPolicy input_no_data_policy(result.mask(), true);
///         OutputNoDataPolicy output_no_data_policy(result.mask(), true);
///
///         result.fill(3);
///
///         fern::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 input_no_data_policy,
///                 output_no_data_policy,
///                 sequential, argument, result);
///
///         BOOST_REQUIRE_EQUAL(result.mask()[0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[1], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[2], false);
///         BOOST_REQUIRE_EQUAL(result[0], 5);
///         BOOST_REQUIRE_EQUAL(result[1], 0);
///         BOOST_REQUIRE_EQUAL(result[2], 5);
///
///         result.fill(3);
///         result.mask()[1] = true;
///
///         fern::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 input_no_data_policy,
///                 output_no_data_policy,
///                 sequential, argument, result);
///
///         BOOST_REQUIRE_EQUAL(result.mask()[0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[1], true);
///         BOOST_REQUIRE_EQUAL(result.mask()[2], false);
///         BOOST_REQUIRE_EQUAL(result[0], 5);
///         BOOST_REQUIRE_EQUAL(result[1], 3);
///         BOOST_REQUIRE_EQUAL(result[2], 5);
///     }
///
///     // empty
///     {
///         Argument argument;
///         Result result;
///
///         InputNoDataPolicy input_no_data_policy(result.mask(), true);
///         OutputNoDataPolicy output_no_data_policy(result.mask(), true);
///
///         fern::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 input_no_data_policy,
///                 output_no_data_policy,
///                 sequential, argument, result);
///
///         BOOST_CHECK(result.empty());
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(array_2d_sequential)
/// {
///     using InputNoDataPolicy = fern::SkipNoData;
///     using OutputNoDataPolicy = fern::DontMarkNoData;
///     using Argument = fern::Array<ArgumentValue, 2>;
///     using Result = fern::Array<ResultValue, 2>;
///
///     OutputNoDataPolicy output_no_data_policy;
///
///     Argument argument{
///         { -2, -1 },
///         {  0,  9 },
///         {  1,  2 }
///     };
///     Result result{
///         { 3, 3 },
///         { 3, 3 },
///         { 3, 3 }
///     };
///
///     fern::unary_local_operation<
///         Algorithm,
///         fern::unary::DiscardDomainErrors,
///         fern::unary::DiscardRangeErrors>(
///             InputNoDataPolicy(),
///             output_no_data_policy,
///             sequential, argument, result);
///
///     BOOST_CHECK_EQUAL(result[0][0], 2);
///     BOOST_CHECK_EQUAL(result[0][1], 1);
///     BOOST_CHECK_EQUAL(result[1][0], 0);
///     BOOST_CHECK_EQUAL(result[1][1], 9);
///     BOOST_CHECK_EQUAL(result[2][0], 1);
///     BOOST_CHECK_EQUAL(result[2][1], 2);
/// }
///
///
/// BOOST_AUTO_TEST_CASE(array_2d_parallel)
/// {
///     using InputNoDataPolicy = fern::SkipNoData;
///     using OutputNoDataPolicy = fern::DontMarkNoData;
///     using Argument = fern::Array<ArgumentValue, 2>;
///     using Result = fern::Array<ResultValue, 2>;
///
///     OutputNoDataPolicy output_no_data_policy;
///
///     Argument argument{
///         { -2, -1 },
///         {  0,  9 },
///         {  1,  2 }
///     };
///     Result result{
///         { 3, 3 },
///         { 3, 3 },
///         { 3, 3 }
///     };
///
///     fern::unary_local_operation<
///         Algorithm,
///         fern::unary::DiscardDomainErrors,
///         fern::unary::DiscardRangeErrors>(
///             InputNoDataPolicy(),
///             output_no_data_policy,
///             parallel, argument, result);
///
///     BOOST_CHECK_EQUAL(result[0][0], 2);
///     BOOST_CHECK_EQUAL(result[0][1], 1);
///     BOOST_CHECK_EQUAL(result[1][0], 0);
///     BOOST_CHECK_EQUAL(result[1][1], 9);
///     BOOST_CHECK_EQUAL(result[2][0], 1);
///     BOOST_CHECK_EQUAL(result[2][1], 2);
/// }
///
///
/// BOOST_AUTO_TEST_CASE(array_2d_masked)
/// {
///     using Argument = fern::MaskedArray<ArgumentValue, 2>;
///     using Result = fern::MaskedArray<ResultValue, 2>;
///     using InputNoDataPolicy = fern::DetectNoDataByValue<fern::Mask<2>>;
///     using OutputNoDataPolicy = fern::MarkNoDataByValue<fern::Mask<2>>;
///
///     {
///         Argument argument{
///             { -2, -1 },
///             {  0,  9 },
///             {  1,  2 }
///         };
///         Result result{
///             { 3, 3 },
///             { 3, 3 },
///             { 3, 3 }
///         };
///
///         InputNoDataPolicy input_no_data_policy(result.mask(), true);
///         OutputNoDataPolicy output_no_data_policy(result.mask(), true);
///
///         result.fill(3);
///
///         fern::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 input_no_data_policy,
///                 output_no_data_policy,
///                 sequential, argument, result);
///
///         BOOST_REQUIRE_EQUAL(result.mask()[0][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[0][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[1][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[1][1], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[2][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[2][1], false);
///         BOOST_CHECK_EQUAL(result[0][0], 2);
///         BOOST_CHECK_EQUAL(result[0][1], 1);
///         BOOST_CHECK_EQUAL(result[1][0], 0);
///         BOOST_CHECK_EQUAL(result[1][1], 9);
///         BOOST_CHECK_EQUAL(result[2][0], 1);
///         BOOST_CHECK_EQUAL(result[2][1], 2);
///
///         result.fill(3);
///         result.mask()[1][1] = true;
///
///         fern::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 input_no_data_policy,
///                 output_no_data_policy,
///                 sequential, argument, result);
///
///         BOOST_REQUIRE_EQUAL(result.mask()[0][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[0][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[1][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[1][1], true);
///         BOOST_REQUIRE_EQUAL(result.mask()[2][0], false);
///         BOOST_REQUIRE_EQUAL(result.mask()[2][1], false);
///         BOOST_CHECK_EQUAL(result[0][0], 2);
///         BOOST_CHECK_EQUAL(result[0][1], 1);
///         BOOST_CHECK_EQUAL(result[1][0], 0);
///         BOOST_CHECK_EQUAL(result[1][1], 3);
///         BOOST_CHECK_EQUAL(result[2][0], 1);
///         BOOST_CHECK_EQUAL(result[2][1], 2);
///     }
///
///     // empty
///     {
///         Argument argument;
///         Result result;
///
///         InputNoDataPolicy input_no_data_policy(result.mask(), true);
///         OutputNoDataPolicy output_no_data_policy(result.mask(), true);
///
///         fern::unary_local_operation<
///             Algorithm,
///             fern::unary::DiscardDomainErrors,
///             fern::unary::DiscardRangeErrors>(
///                 input_no_data_policy,
///                 output_no_data_policy,
///                 sequential, argument, result);
///
///         BOOST_CHECK(result.empty());
///     }
/// }

/// #include "fern/feature/core/array_traits.h"
/// #include "fern/feature/core/masked_array_traits.h"
/// #include "fern/feature/core/masked_constant_traits.h"
/// #include "fern/feature/core/test/masked_scalar.h"
/// #include "fern/core/vector_traits.h"
/// #include "fern/algorithm/policy/policies.h"
/// #include "fern/algorithm/statistic/count.h"
/// #include "fern/algorithm/algebra/executor.h"
/// #include "fern/algorithm/algebra/elementary/equal.h"

// BOOST_AUTO_TEST_CASE(masked_d0_array_d0_array)
// {
//     fern::MaskedScalar<int8_t> constant1;
//     fern::MaskedScalar<int32_t> constant2;
//     fern::MaskedScalar<int32_t> result;
//
//     // MaskedConstants with non-masking equal. ---------------------------------
//     // Constants are not masked.
//     constant1.mask() = false;
//     constant1.value() = 5;
//     constant2.mask() = false;
//     constant2.value() = 5;
//     result.value() = 9;
//     result.mask() = false;
//     fern::algebra::add(constant1, constant2, result);
//     BOOST_CHECK(!result.mask());
//     BOOST_CHECK_EQUAL(result.value(), 10);
//
//     // Constant is masked.
//     constant1.mask() = true;
//     constant1.value() = 5;
//     constant2.mask() = false;
//     constant2.value() = 5;
//     result.value() = 9;
//     result.mask() = false;
//     fern::algebra::add(constant1, constant2, result);
//     BOOST_CHECK(!result.mask());
//     BOOST_CHECK_EQUAL(result.value(), 10);
//
//     // MaskedScalar with masking add. ----------------------------------------
//     using InputNoDataPolicy = fern::DetectNoDataByValue<bool>;
//     using OutputNoDataPolicy = fern::MarkNoDataByValue<bool>;
//
//     // Constants are not masked.
//     constant1.mask() = false;
//     constant1.value() = 5;
//     constant2.mask() = false;
//     constant2.value() = 5;
//     result.value() = 9;
//     result.mask() = false;
//     fern::algebra::add<fern::MaskedScalar<int8_t>,
//         fern::MaskedScalar<int32_t>, fern::MaskedScalar<int32_t>,
//         fern::binary::DiscardDomainErrors, fern::binary::DiscardRangeErrors, InputNoDataPolicy,
//         OutputNoDataPolicy>(
//             InputNoDataPolicy(result.mask(), true),
//             OutputNoDataPolicy(result.mask(), true),
//             constant1, constant2, result);
//     BOOST_CHECK(!result.mask());
//     BOOST_CHECK_EQUAL(result.value(), 10);
//
//     // Constants are masked.
//     constant1.value() = 5;
//     constant1.mask() = true;
//     constant2.value() = 5;
//     constant2.mask() = false;
//     result.value() = 9;
//     result.mask() = constant1.mask() || constant2.mask();
//     fern::algebra::add<fern::MaskedScalar<int8_t>,
//         fern::MaskedScalar<int32_t>, fern::MaskedScalar<int32_t>,
//         fern::binary::DiscardDomainErrors, fern::binary::DiscardRangeErrors, InputNoDataPolicy,
//         OutputNoDataPolicy>(
//             InputNoDataPolicy(result.mask(), true),
//             OutputNoDataPolicy(result.mask(), true),
//             constant1, constant2, result);
//     BOOST_CHECK(result.mask());
//     BOOST_CHECK_EQUAL(result.value(), 9);
// }
//
//
// BOOST_AUTO_TEST_CASE(d1_array_d1_array)
// {
//     // vector
//     {
//         std::vector<int32_t> array1{1, 2, 3};
//         std::vector<uint64_t> array2{1, 4, 3};
//         std::vector<int64_t> result(3);
//         fern::algebra::add(array1, array2, result);
//         BOOST_CHECK_EQUAL(result[0], 2);
//         BOOST_CHECK_EQUAL(result[1], 6);
//         BOOST_CHECK_EQUAL(result[2], 6);
//     }
//
//     // 1d array
//     {
//         fern::Array<uint8_t, 1> array1{1, 2, 3};
//         fern::Array<uint16_t, 1> array2{1, 4, 3};
//         std::vector<uint16_t> result(3);
//         fern::algebra::add(array1, array2, result);
//         BOOST_CHECK_EQUAL(result[0], 2);
//         BOOST_CHECK_EQUAL(result[1], 6);
//         BOOST_CHECK_EQUAL(result[2], 6);
//     }
//
//     // empty
//     {
//         std::vector<int32_t> array1;
//         std::vector<int32_t> array2;
//         std::vector<int32_t> result;
//         fern::algebra::add(array1, array2, result);
//         BOOST_CHECK(result.empty());
//     }
// }
//
//
// BOOST_AUTO_TEST_CASE(masked_d1_array_masked_d1_array)
// {
//     using InputNoDataPolicy = fern::DetectNoDataByValue<fern::Mask<1>>;
//     using OutputNoDataPolicy = fern::MarkNoDataByValue<fern::Mask<1>>;
//
//     fern::MaskedArray<int32_t, 1> array1{1, 2, 3};
//     fern::MaskedArray<int32_t, 1> array2{1, 4, 3};
//
//     // 1d masked arrays with non-masking add
//     {
//         fern::MaskedArray<int32_t, 1> result(3);
//         fern::algebra::add(array1, array2, result);
//         BOOST_CHECK_EQUAL(result.mask()[0], false);
//         BOOST_CHECK_EQUAL(result.mask()[1], false);
//         BOOST_CHECK_EQUAL(result.mask()[2], false);
//         BOOST_CHECK_EQUAL(result[0], 2);
//         BOOST_CHECK_EQUAL(result[1], 6);
//         BOOST_CHECK_EQUAL(result[2], 6);
//     }
//
//     // 1d masked arrays with masking add
//     {
//         fern::MaskedArray<int32_t, 1> result(3);
//         result.mask()[2] = true;
//         fern::algebra::add<
//             fern::MaskedArray<int32_t, 1>,
//             fern::MaskedArray<int32_t, 1>,
//             fern::MaskedArray<int32_t, 1>,
//             fern::binary::DiscardDomainErrors,
//             fern::binary::DiscardRangeErrors,
//             InputNoDataPolicy,
//             OutputNoDataPolicy>(
//                 InputNoDataPolicy(result.mask(), true),
//                 OutputNoDataPolicy(result.mask(), true),
//                 array1, array2, result);
//         BOOST_CHECK_EQUAL(result.mask()[0], false);
//         BOOST_CHECK_EQUAL(result.mask()[1], false);
//         BOOST_CHECK_EQUAL(result.mask()[2], true);
//         BOOST_CHECK_EQUAL(result[0], 2);
//         BOOST_CHECK_EQUAL(result[1], 6);
//         BOOST_CHECK_EQUAL(result[2], 0);  // <-- Not touched.
//
//         // Mask the whole input. Result must be masked too.
//         result.mask_all();
//         fern::algebra::add<
//             fern::MaskedArray<int32_t, 1>,
//             fern::MaskedArray<int32_t, 1>,
//             fern::MaskedArray<int32_t, 1>,
//             fern::binary::DiscardDomainErrors,
//             fern::binary::DiscardRangeErrors,
//             InputNoDataPolicy,
//             OutputNoDataPolicy>(
//                 InputNoDataPolicy(result.mask(), true),
//                 OutputNoDataPolicy(result.mask(), true),
//                 array1, array2, result);
//         BOOST_CHECK_EQUAL(result.mask()[0], true);
//         BOOST_CHECK_EQUAL(result.mask()[1], true);
//         BOOST_CHECK_EQUAL(result.mask()[2], true);
//     }
//
//     // empty
//     {
//         fern::MaskedArray<int32_t, 1> empty_array;
//         fern::MaskedArray<int32_t, 1> result;
//         fern::algebra::add<
//             fern::MaskedArray<int32_t, 1>,
//             fern::MaskedArray<int32_t, 1>,
//             fern::MaskedArray<int32_t, 1>,
//             fern::binary::DiscardDomainErrors,
//             fern::binary::DiscardRangeErrors,
//             InputNoDataPolicy,
//             OutputNoDataPolicy>(
//                 InputNoDataPolicy(result.mask(), true),
//                 OutputNoDataPolicy(result.mask(), true),
//                 empty_array, empty_array, result);
//         BOOST_CHECK(result.empty());
//     }
// }
//
//
// BOOST_AUTO_TEST_CASE(d2_array_d2_array)
// {
//     // 2d array
//     {
//         fern::Array<int8_t, 2> array1{
//             { -2, -1 },
//             {  0,  9 },
//             {  1,  2 }
//         };
//         fern::Array<int8_t, 2> array2{
//             { -2, -1 },
//             {  5,  9 },
//             {  1,  2 }
//         };
//         fern::Array<int8_t, 2> result{
//             { 0, 0 },
//             { 0, 0 },
//             { 0, 0 }
//         };
//         fern::algebra::add(array1, array2, result);
//         BOOST_CHECK_EQUAL(result[0][0], -4);
//         BOOST_CHECK_EQUAL(result[0][1], -2);
//         BOOST_CHECK_EQUAL(result[1][0], 5);
//         BOOST_CHECK_EQUAL(result[1][1], 18);
//         BOOST_CHECK_EQUAL(result[2][0], 2);
//         BOOST_CHECK_EQUAL(result[2][1], 4);
//     }
// }
//
//
// BOOST_AUTO_TEST_CASE(masked_d2_array_masked_d2_array)
// {
//     fern::MaskedArray<int8_t, 2> array1{
//         { -2, -1 },
//         {  0,  9 },
//         {  1,  2 }
//     };
//     fern::MaskedArray<int8_t, 2> array2{
//         { -2, -1 },
//         {  5,  9 },
//         {  1,  2 }
//     };
//
//     // 2d masked array with non-masking add
//     {
//         fern::MaskedArray<int8_t, 2> result{
//             { 0, 0 },
//             { 0, 0 },
//             { 0, 0 }
//         };
//         fern::algebra::add(array1, array2, result);
//         BOOST_CHECK_EQUAL(result[0][0], -4);
//         BOOST_CHECK_EQUAL(result[0][1], -2);
//         BOOST_CHECK_EQUAL(result[1][0], 5);
//         BOOST_CHECK_EQUAL(result[1][1], 18);
//         BOOST_CHECK_EQUAL(result[2][0], 2);
//         BOOST_CHECK_EQUAL(result[2][1], 4);
//     }
//
//     // 2d masked arrays with masking add
//     {
//         // TODO
//     }
// }
//
//
// BOOST_AUTO_TEST_CASE(concurrent_d2_array)
// {
//     size_t const nr_rows = 6000;
//     size_t const nr_cols = 4000;
//     auto const extents = fern::extents[nr_rows][nr_cols];
//     fern::Array<int32_t, 2> array1(extents);
//     fern::Array<int32_t, 2> array2(extents);
//     fern::Array<int32_t, 2> plus_result_we_get(extents);
//     fern::Array<int32_t, 2> plus_result_we_want(extents);
//     fern::Array<bool, 2> equal_result_we_get(extents, true);
//     size_t count_result_we_get;
//     size_t const count_result_we_want = nr_rows * nr_cols;
//     fern::algebra::Add<
//         fern::Array<int32_t, 2>,
//         fern::Array<int32_t, 2>,
//         fern::Array<int32_t, 2>> add;
//     fern::algebra::Equal<
//         fern::Array<int32_t, 2>,
//         fern::Array<int32_t, 2>,
//         fern::Array<bool, 2>> equal;
//     fern::statistic::Count<
//         fern::Array<bool, 2>,
//         size_t> count;
//
//     std::iota(array1.data(), array1.data() + array1.num_elements(), 0);
//     std::iota(array2.data(), array2.data() + array2.num_elements(), 0);
//     std::transform(array1.data(), array1.data() + array1.num_elements(),
//         plus_result_we_want.data(), [](int32_t value){ return value + value; });
//
//     // Serial.
//     {
//         fern::serial::execute(add, array1, array2, plus_result_we_get);
//         fern::serial::execute(equal, plus_result_we_get, plus_result_we_want,
//             equal_result_we_get);
//         fern::serial::execute(count, equal_result_we_get, true,
//             count_result_we_get);
//         BOOST_CHECK_EQUAL(count_result_we_get, count_result_we_want);
//     }
//
//     // Concurrent.
//     {
//         fern::concurrent::execute(add, array1, array2, plus_result_we_get);
//         fern::concurrent::execute(equal, plus_result_we_get,
//             plus_result_we_want, equal_result_we_get);
//         fern::concurrent::execute(count, equal_result_we_get, true,
//             count_result_we_get);
//         BOOST_CHECK_EQUAL(count_result_we_get, count_result_we_want);
//     }
// }
//
//
// BOOST_AUTO_TEST_CASE(concurrent_masked_d2_array)
// {
//     using InputNoDataPolicy = fern::SkipNoData;
//     using OutputNoDataPolicy = fern::MarkNoDataByValue<fern::Mask<2>>;
//
//     size_t const nr_rows = 6000;
//     size_t const nr_cols = 4000;
//     auto const extents = fern::extents[nr_rows][nr_cols];
//     fern::MaskedArray<int32_t, 2> array1(extents);
//     fern::MaskedArray<int32_t, 2> array2(extents);
//     fern::MaskedArray<int32_t, 2> plus_result_we_get(extents);
//     fern::MaskedArray<int32_t, 2> plus_result_we_want(extents);
//     fern::MaskedArray<bool, 2> equal_result_we_get(extents, true);
//     fern::MaskedScalar<size_t> count_result_we_get;
//     fern::MaskedScalar<size_t> const count_result_we_want{nr_rows * nr_cols};
//     fern::algebra::Add<
//         fern::MaskedArray<int32_t, 2>,
//         fern::MaskedArray<int32_t, 2>,
//         fern::MaskedArray<int32_t, 2>,
//         fern::binary::DiscardDomainErrors,
//         fern::binary::DiscardRangeErrors,
//         InputNoDataPolicy,
//         OutputNoDataPolicy> add(
//             InputNoDataPolicy(),
//             OutputNoDataPolicy(plus_result_we_get.mask(), true));
//     fern::algebra::Equal<
//         fern::MaskedArray<int32_t, 2>,
//         fern::MaskedArray<int32_t, 2>,
//         fern::MaskedArray<bool, 2>,
//         fern::binary::DiscardDomainErrors,
//         fern::binary::DiscardRangeErrors,
//         InputNoDataPolicy,
//         OutputNoDataPolicy> equal(
//             InputNoDataPolicy(),
//             OutputNoDataPolicy(equal_result_we_get.mask(), true));
//     fern::statistic::Count<
//         fern::MaskedArray<bool, 2>,
//         fern::MaskedScalar<size_t>,
//         InputNoDataPolicy,
//         fern::MarkNoDataByValue<bool>> count(
//             InputNoDataPolicy(),
//             fern::MarkNoDataByValue<bool>(count_result_we_get.mask(), true));
//
//     std::iota(array1.data(), array1.data() + array1.num_elements(), 0);
//     std::iota(array2.data(), array2.data() + array2.num_elements(), 0);
//     std::transform(array1.data(), array1.data() + array1.num_elements(),
//         plus_result_we_want.data(), [](int32_t value){ return value + value; });
//
//     // Verify executor can handle masked result.
//     fern::concurrent::execute(add, array1, array2, plus_result_we_get);
//     fern::concurrent::execute(equal, plus_result_we_get,
//         plus_result_we_want, equal_result_we_get);
//     fern::concurrent::execute(count, equal_result_we_get, true,
//         count_result_we_get);
//     BOOST_CHECK_EQUAL(count_result_we_get, count_result_we_want);
// }
//
//
// // TODO Test 1d array + 0d array
// //      Test 2d array + 1d array
// //      etc
// // TODO Stuff below.

/// BOOST_AUTO_TEST_CASE(value)
/// {
///     verify_value<int8_t, int8_t, int8_t>(-5, 6, 1);
///
///     verify_value<uint16_t, int8_t>(fern::TypeTraits<uint16_t>::max, 2,
///         int32_t(fern::TypeTraits<uint16_t>::max) + int32_t(2));
///
///     verify_value<uint32_t, int8_t>(fern::TypeTraits<uint32_t>::max, 2,
///         int64_t(fern::TypeTraits<uint32_t>::max) + int64_t(2));
///
///     verify_value<uint64_t, int64_t>(
///         fern::TypeTraits<uint64_t>::max,
///         fern::TypeTraits<int64_t>::max,
///         int64_t(fern::TypeTraits<uint64_t>::max) +
///             fern::TypeTraits<int64_t>::max);
/// }
///
///
/// template<
///     class A1,
///     class A2>
/// struct DomainPolicyHost:
///     public fern::add::OutOfDomainPolicy<A1, A2>
/// {
/// };
///
///
/// BOOST_AUTO_TEST_CASE(domain)
/// {
///     {
///         DomainPolicyHost<int32_t, int32_t> domain;
///         BOOST_CHECK(domain.within_domain(-1, 2));
///     }
///     {
///         DomainPolicyHost<uint8_t, double> domain;
///         BOOST_CHECK(domain.within_domain(1, 2.0));
///     }
/// }
///
///
/// template<
///     class A1,
///     class A2>
/// struct RangePolicyHost:
///     public fern::add::OutOfRangePolicy<A1, A2>
/// {
/// };
///
///
/// template<
///     class A1,
///     class A2>
/// void verify_range_check(
///     A1 const& argument1,
///     A2 const& argument2,
///     bool const within)
/// {
///     fern::algebra::Add<A1, A2> operation;
///     typename fern::algebra::Add<A1, A2>::R result;
///     RangePolicyHost<A1, A2> range;
///
///     operation(argument1, argument2, result);
///     BOOST_CHECK_EQUAL((range.within_range(argument1, argument2, result)),
///         within);
/// }
///
///
/// BOOST_AUTO_TEST_CASE(range)
/// {
///     int8_t const min_int8 = fern::TypeTraits<int8_t>::min;
///     int8_t const max_int8 = fern::TypeTraits<int8_t>::max;
///     uint8_t const max_uint8 = fern::TypeTraits<uint8_t>::max;
///     uint16_t const max_uint16 = fern::TypeTraits<uint16_t>::max;
///     uint32_t const max_uint32 = fern::TypeTraits<uint32_t>::max;
///     int64_t const min_int64 = fern::TypeTraits<int64_t>::min;
///     int64_t const max_int64 = fern::TypeTraits<int64_t>::max;
///     uint64_t const max_uint64 = fern::TypeTraits<uint64_t>::max;
///
///     // signed + signed
///     verify_range_check<int8_t, int8_t>(-5, 6, true);
///     verify_range_check<int8_t, int8_t>(max_int8, 1, false);
///     verify_range_check<int8_t, int8_t>(min_int8, -1, false);
///     verify_range_check<int64_t, int64_t>(min_int64, -1, false);
///
///     // unsigned + unsigned
///     verify_range_check<uint8_t, uint8_t>(5, 6, true);
///     verify_range_check<uint8_t, uint8_t>(max_uint8, 1, false);
///     verify_range_check<uint8_t, uint16_t>(max_uint8, 1, true);
///
///     // signed + unsigned
///     // unsigned + signed
///     verify_range_check<int8_t, uint8_t>(5, 6, true);
///     verify_range_check<uint8_t, int8_t>(5, 6, true);
///     verify_range_check<uint16_t, int8_t>(max_uint16, 2, true);
///     verify_range_check<uint32_t, int8_t>(max_uint32, 2, true);
///     verify_range_check<uint64_t, int64_t>(max_uint64, max_int64, false);
///
///     // float + float
///     float const max_float32 = fern::TypeTraits<float>::max;
///     verify_range_check<float, float>(5.0, 6.0, true);
///     verify_range_check<float, float>(max_float32, max_float32 * 20, false);
///
///     // float + signed
///     // unsigned + float
///     verify_range_check<float, int8_t>(5.0, 6, true);
///     verify_range_check<uint8_t, float>(5, 6.0, true);
/// }
///
///
/// BOOST_AUTO_TEST_CASE(argument_types)
/// {
///     // Verify that we can pass in all kinds of collection types.
///
///     // constant + constant
///     {
///         uint8_t argument1(5);
///         uint8_t argument2(6);
///         using R = fern::Result<uint8_t, uint8_t>::type;
///         R result;
///
///         fern::algebra::add(argument1, argument2, result);
///
///         BOOST_CHECK_EQUAL(result, 11u);
///     }
///
///     // constant + vector
///     {
///         uint8_t argument1(5);
///         std::vector<uint8_t> argument2({1, 2, 3});
///         using R = fern::Result<uint8_t, uint8_t>::type;
///         std::vector<R> result(argument2.size());
///
///         fern::algebra::add(argument1, argument2, result);
///
///         BOOST_REQUIRE_EQUAL(result.size(), 3u);
///         BOOST_CHECK_EQUAL(result[0], 6u);
///         BOOST_CHECK_EQUAL(result[1], 7u);
///         BOOST_CHECK_EQUAL(result[2], 8u);
///     }
///
///     // vector + constant
///     {
///         std::vector<uint8_t> argument1({1, 2, 3});
///         uint8_t argument2(5);
///         using R = fern::Result<uint8_t, uint8_t>::type;
///         std::vector<R> result(argument1.size());
///
///         fern::algebra::add(argument1, argument2, result);
///
///         BOOST_REQUIRE_EQUAL(result.size(), 3u);
///         BOOST_CHECK_EQUAL(result[0], 6u);
///         BOOST_CHECK_EQUAL(result[1], 7u);
///         BOOST_CHECK_EQUAL(result[2], 8u);
///     }
///
///     // vector + vector
///     {
///         std::vector<uint8_t> argument1({1, 2, 3});
///         std::vector<uint8_t> argument2({4, 5, 6});
///         using R = fern::Result<uint8_t, uint8_t>::type;
///         std::vector<R> result(argument1.size());
///
///         fern::algebra::add(argument1, argument2, result);
///
///         BOOST_REQUIRE_EQUAL(result.size(), 3u);
///         BOOST_CHECK_EQUAL(result[0], 5u);
///         BOOST_CHECK_EQUAL(result[1], 7u);
///         BOOST_CHECK_EQUAL(result[2], 9u);
///     }
///
///     // array + array
///     {
///         fern::Array<int8_t, 2> argument(fern::extents[3][2]);
///         argument[0][0] = -2;
///         argument[0][1] = -1;
///         argument[1][0] =  0;
///         argument[1][1] =  9;
///         argument[2][0] =  1;
///         argument[2][1] =  2;
///         using R = fern::Result<int8_t, int8_t>::type;
///         fern::Array<R, 2> result(fern::extents[3][2]);
///
///         fern::algebra::add(argument, argument, result);
///
///         BOOST_CHECK_EQUAL(result[0][0], -4);
///         BOOST_CHECK_EQUAL(result[0][1], -2);
///         BOOST_CHECK_EQUAL(result[1][0],  0);
///         BOOST_CHECK_EQUAL(result[1][1], 18);
///         BOOST_CHECK_EQUAL(result[2][0],  2);
///         BOOST_CHECK_EQUAL(result[2][1],  4);
///     }
///
///     // masked_array + masked_array
///     {
///         fern::MaskedArray<int8_t, 2> argument(fern::extents[3][2]);
///         argument[0][0] = -2;
///         argument[0][1] = -1;
///         argument[1][0] =  0;
///         argument.mask()[1][1] =  true;
///         argument[1][1] =  9;
///         argument[2][0] =  1;
///         argument[2][1] =  2;
///         using R = fern::Result<int8_t, int8_t>::type;
///         fern::MaskedArray<R, 2> result(fern::extents[3][2]);
///
///         fern::algebra::add(argument, argument, result);
///
///         BOOST_CHECK(!result.mask()[0][0]);
///         BOOST_CHECK_EQUAL(result[0][0], -4);
///
///         BOOST_CHECK(!result.mask()[0][1]);
///         BOOST_CHECK_EQUAL(result[0][1], -2);
///
///         BOOST_CHECK(!result.mask()[1][0]);
///         BOOST_CHECK_EQUAL(result[1][0],  0);
///
///         // Although the input data has a mask, the default policy discards
///         // it. So the result doesn't have masked values.
///         BOOST_CHECK(!result.mask()[1][1]);
///         BOOST_CHECK_EQUAL(result[1][1], 18);
///
///         BOOST_CHECK(!result.mask()[2][0]);
///         BOOST_CHECK_EQUAL(result[2][0],  2);
///         BOOST_CHECK(!result.mask()[2][1]);
///         BOOST_CHECK_EQUAL(result[2][1],  4);
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(no_data)
/// {
///     size_t const nr_rows = 3;
///     size_t const nr_cols = 2;
///     auto extents = fern::extents[nr_rows][nr_cols];
///
///     fern::MaskedArray<int8_t, 2> argument1(extents);
///     argument1[0][0] = -2;
///     argument1[0][1] = -1;
///     argument1[1][0] =  0;
///     argument1.mask()[1][1] =  true;
///     argument1[2][0] =  1;
///     argument1[2][1] =  2;
///
///     fern::MaskedArray<int8_t, 2> argument2(extents);
///     argument2[0][0] = -2;
///     argument2[0][1] = -1;
///     argument2[1][0] =  0;
///     argument2[1][1] =  9;
///     argument2.mask()[2][0] =  true;
///     argument2[2][1] =  2;
///
///     int8_t argument3 = 5;
///
///     // masked_array + masked_array
///     {
///         // Create room for the result.
///         // Set the mask.
///         using R = fern::Result<int8_t, int8_t>::type;
///         fern::MaskedArray<R, 2> result(extents);
///         result.set_mask(argument1.mask(), true);
///         result.set_mask(argument2.mask(), true);
///
///         using A1 = decltype(argument1);
///         using A2 = decltype(argument2);
///         using A1Value = fern::DataTypeTraits<A1>::value_type;
///         using A2Value = fern::DataTypeTraits<A2>::value_type;
///         using OutOfDomainPolicy = fern::DiscardDomainErrors<A1Value, A2Value>;
///         using OutOfRangePolicy = fern::add::OutOfRangePolicy<A1Value, A2Value>;
///         using NoDataPolicy = fern::MarkNoDataByValue<bool, fern::Mask<2>>;
///         using Add = fern::algebra::Add<A1, A2, OutOfDomainPolicy, OutOfRangePolicy,
///             NoDataPolicy>;
///
///         Add add(NoDataPolicy(result.mask(), true));
///
///         add(argument1, argument2, result);
///
///         BOOST_CHECK(!result.mask()[0][0]);
///         BOOST_CHECK_EQUAL(result[0][0], -4);
///
///         BOOST_CHECK(!result.mask()[0][1]);
///         BOOST_CHECK_EQUAL(result[0][1], -2);
///
///         BOOST_CHECK(!result.mask()[1][0]);
///         BOOST_CHECK_EQUAL(result[1][0],  0);
///
///         BOOST_CHECK( result.mask()[1][1]);
///         // Value is masked: it is undefined.
///         // BOOST_CHECK_EQUAL(result[1][1], 18);
///
///         BOOST_CHECK(result.mask()[2][0]);
///         // Value is masked.
///         // BOOST_CHECK_EQUAL(result[2][0],  2);
///
///         BOOST_CHECK(!result.mask()[2][1]);
///         BOOST_CHECK_EQUAL(result[2][1],  4);
///     }
///
///     // masked_array + 5
///     {
///         // Create room for the result.
///         // Set the mask.
///         using R = fern::Result<int8_t, int8_t>::type;
///         fern::MaskedArray<R, 2> result(extents);
///         result.set_mask(argument1.mask(), true);
///
///         using A1 = decltype(argument1);
///         using A2 = decltype(argument3);
///         using A1Value = fern::DataTypeTraits<A1>::value_type;
///         using A2Value = fern::DataTypeTraits<A2>::value_type;
///         using OutOfDomainPolicy = fern::DiscardDomainErrors<A1Value, A2Value>;
///         using OutOfRangePolicy = fern::add::OutOfRangePolicy<A1Value, A2Value>;
///         using NoDataPolicy = fern::MarkNoDataByValue<bool, fern::Mask<2>>;
///         using Add = fern::algebra::Add<A1, A2, OutOfDomainPolicy, OutOfRangePolicy,
///             NoDataPolicy>;
///
///         Add add(NoDataPolicy(result.mask(), true));
///
///         add(argument1, argument3, result);
///
///         BOOST_CHECK(!result.mask()[0][0]);
///         BOOST_CHECK_EQUAL(result[0][0], 3);
///
///         BOOST_CHECK(!result.mask()[0][1]);
///         BOOST_CHECK_EQUAL(result[0][1], 4);
///
///         BOOST_CHECK(!result.mask()[1][0]);
///         BOOST_CHECK_EQUAL(result[1][0], 5);
///
///         BOOST_CHECK( result.mask()[1][1]);
///
///         BOOST_CHECK(!result.mask()[2][0]);
///         BOOST_CHECK_EQUAL(result[2][0], 6);
///
///         BOOST_CHECK(!result.mask()[2][1]);
///         BOOST_CHECK_EQUAL(result[2][1], 7);
///     }
///
///     // 5 + masked_array
///     {
///         // Create room for the result.
///         // Set the mask.
///         using R = fern::Result<int8_t, int8_t>::type;
///         fern::MaskedArray<R, 2> result(extents);
///         result.set_mask(argument1.mask(), true);
///
///         using A1 = decltype(argument3);
///         using A2 = decltype(argument1);
///         using A1Value = fern::DataTypeTraits<A1>::value_type;
///         using A2Value = fern::DataTypeTraits<A2>::value_type;
///         using OutOfDomainPolicy = fern::DiscardDomainErrors<A1Value, A2Value>;
///         using OutOfRangePolicy = fern::add::OutOfRangePolicy<A1Value, A2Value>;
///         using NoDataPolicy = fern::MarkNoDataByValue<bool, fern::Mask<2>>;
///         using Add = fern::algebra::Add<A1, A2, OutOfDomainPolicy, OutOfRangePolicy,
///             NoDataPolicy>;
///
///         Add add(NoDataPolicy(result.mask(), true));
///
///         add(argument3, argument1, result);
///
///         BOOST_CHECK(!result.mask()[0][0]);
///         BOOST_CHECK_EQUAL(result[0][0], 3);
///
///         BOOST_CHECK(!result.mask()[0][1]);
///         BOOST_CHECK_EQUAL(result[0][1], 4);
///
///         BOOST_CHECK(!result.mask()[1][0]);
///         BOOST_CHECK_EQUAL(result[1][0], 5);
///
///         BOOST_CHECK( result.mask()[1][1]);
///
///         BOOST_CHECK(!result.mask()[2][0]);
///         BOOST_CHECK_EQUAL(result[2][0], 6);
///
///         BOOST_CHECK(!result.mask()[2][1]);
///         BOOST_CHECK_EQUAL(result[2][1], 7);
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(threading)
/// {
///     // Create a somewhat larger array.
///     size_t const nr_rows = 6000;
///     size_t const nr_cols = 4000;
///     auto extents = fern::extents[nr_rows][nr_cols];
///     fern::Array<int8_t, 2> argument1(extents);
///
///     // Fill it with 0, 1, 2, 3, ...
///     std::iota(argument1.data(), argument1.data() + argument1.num_elements(), 0);
///
///     int8_t argument2 = 5;
///
///     // Create array with values that should be in the result.
///     fern::Array<int8_t, 2> result_we_want(extents);
///     std::iota(result_we_want.data(), result_we_want.data() +
///         result_we_want.num_elements(), 5);
///
///     {
///         // Add collection and constant.
///         fern::algebra::Add<fern::Array<int8_t, 2>, int8_t> add;
///         fern::Array<int8_t, 2> plus_result(extents);
///
///         // Compare result with result we want.
///         fern::algebra::Add<fern::Array<int8_t, 2>, fern::Array<int8_t, 2>>
///             add;
///         fern::Array<bool, 2> equal_result(extents);
///
///         // Count the number of equal values.
///         fern::statistic::Count<fern::Array<bool, 2>, bool> count;
///         size_t count_result;
///
///         // Serial.
///         {
///             fern::serial::execute(add, argument1, argument2, plus_result);
///             fern::serial::execute(equal, plus_result, result_we_want,
///                 equal_result);
///             fern::serial::execute(count, equal_result, true, count_result);
///
///             // Make sure the number of equal values equals the number of
///             // elements.
///             BOOST_CHECK_EQUAL(count_result, equal_result.num_elements());
///         }
///
///         // Concurrent.
///         {
///             fern::concurrent::execute(add, argument1, argument2, plus_result);
///             fern::concurrent::execute(equal, plus_result, result_we_want,
///                 equal_result);
///             fern::concurrent::execute(count, equal_result, true, count_result);
///
///             // Make sure the number of equal values equals the number of
///             // elements.
///             BOOST_CHECK_EQUAL(count_result, equal_result.num_elements());
///         }
///     }
///
///     // TODO Make this work for masked arrays too.
/// }

/// BOOST_AUTO_TEST_CASE(masked_d0_array_d0_array)
/// {
///     fern::MaskedScalar<int8_t> constant1;
///     fern::MaskedScalar<int32_t> constant2;
///     fern::MaskedScalar<bool> result_we_get;
///
///     // MaskedConstants with non-masking equal. ---------------------------------
///     // Constants are not masked.
///     constant1.mask() = false;
///     constant1.value() = 5;
///     constant2.mask() = false;
///     constant2.value() = 5;
///     result_we_get.value() = false;
///     result_we_get.mask() = false;
///     fern::algebra::equal(constant1, constant2, result_we_get);
///     BOOST_CHECK(!result_we_get.mask());
///     BOOST_CHECK_EQUAL(result_we_get.value(), true);
///
///     // Constant is masked.
///     constant1.mask() = true;
///     constant1.value() = 5;
///     constant2.mask() = false;
///     constant2.value() = 5;
///     result_we_get.value() = false;
///     result_we_get.mask() = false;
///     fern::algebra::equal(constant1, constant2, result_we_get);
///     BOOST_CHECK(!result_we_get.mask());
///     BOOST_CHECK_EQUAL(result_we_get.value(), true);
///
///     // MaskedScalar with masking equal. --------------------------------------
///     using InputNoDataPolicy = fern::DetectNoDataByValue<bool>;
///     using OutputNoDataPolicy = fern::MarkNoDataByValue<bool>;
///
///     // Constants are not masked.
///     constant1.mask() = false;
///     constant1.value() = 5;
///     constant2.mask() = false;
///     constant2.value() = 5;
///     result_we_get.value() = false;
///     result_we_get.mask() = constant1.mask() || constant2.mask();
///     fern::algebra::equal<fern::MaskedScalar<int8_t>,
///         fern::MaskedScalar<int32_t>, fern::MaskedScalar<bool>,
///         fern::binary::DiscardDomainErrors, fern::binary::DiscardRangeErrors,
///         InputNoDataPolicy,
///         OutputNoDataPolicy>(
///             InputNoDataPolicy(result_we_get.mask(), true),
///             OutputNoDataPolicy(result_we_get.mask(), true),
///             constant1, constant2, result_we_get);
///     BOOST_CHECK(!result_we_get.mask());
///     BOOST_CHECK_EQUAL(result_we_get.value(), true);
///
///     // Constants are masked.
///     constant1.value() = 5;
///     constant1.mask() = true;
///     constant2.value() = 5;
///     constant2.mask() = false;
///     result_we_get.value() = false;
///     result_we_get.mask() = constant1.mask() || constant2.mask();
///     fern::algebra::equal<fern::MaskedScalar<int8_t>,
///         fern::MaskedScalar<int32_t>, fern::MaskedScalar<bool>,
///         fern::binary::DiscardDomainErrors, fern::binary::DiscardRangeErrors,
///         InputNoDataPolicy,
///         OutputNoDataPolicy>(
///             InputNoDataPolicy(result_we_get.mask(), true),
///             OutputNoDataPolicy(result_we_get.mask(), true),
///             constant1, constant2, result_we_get);
///     BOOST_CHECK(result_we_get.mask());
///     BOOST_CHECK_EQUAL(result_we_get.value(), false);
/// }
///
///
/// BOOST_AUTO_TEST_CASE(d1_array_d1_array)
/// {
///     // vector
///     {
///         std::vector<int32_t> array1{1, 2, 3};
///         std::vector<uint64_t> array2{1, 4, 3};
///         std::vector<bool> result(3);
///         fern::algebra::equal(array1, array2, result);
///         BOOST_CHECK_EQUAL(result[0], true);
///         BOOST_CHECK_EQUAL(result[1], false);
///         BOOST_CHECK_EQUAL(result[2], true);
///     }
///
///     // 1d array
///     {
///         fern::Array<uint8_t, 1> array1{1, 2, 3};
///         fern::Array<uint16_t, 1> array2{1, 4, 3};
///         std::vector<bool> result(3);
///         fern::algebra::equal(array1, array2, result);
///         BOOST_CHECK_EQUAL(result[0], true);
///         BOOST_CHECK_EQUAL(result[1], false);
///         BOOST_CHECK_EQUAL(result[2], true);
///     }
///
///     // empty
///     {
///         std::vector<int32_t> array1;
///         std::vector<int32_t> array2;
///         std::vector<bool> result;
///         fern::algebra::equal(array1, array2, result);
///         BOOST_CHECK(result.empty());
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(masked_d1_array)
/// {
///     using InputNoDataPolicy = fern::DetectNoDataByValue<fern::Mask<1>>;
///     using OutputNoDataPolicy = fern::MarkNoDataByValue<fern::Mask<1>>;
///
///     fern::MaskedArray<int32_t, 1> array1{1, 2, 3};
///     fern::MaskedArray<int32_t, 1> array2{1, 4, 3};
///
///     // 1d masked arrays with non-masking equal
///     {
///         fern::MaskedArray<bool, 1> result(3, false);
///         fern::algebra::equal(array1, array2, result);
///         BOOST_CHECK_EQUAL(result.mask()[0], false);
///         BOOST_CHECK_EQUAL(result.mask()[1], false);
///         BOOST_CHECK_EQUAL(result.mask()[2], false);
///         BOOST_CHECK_EQUAL(result[0], true);
///         BOOST_CHECK_EQUAL(result[1], false);
///         BOOST_CHECK_EQUAL(result[2], true);
///     }
///
///     // 1d masked arrays with masking equal
///     {
///         fern::MaskedArray<bool, 1> result(3, false);
///         result.mask()[2] = true;
///         fern::algebra::equal<
///             fern::MaskedArray<int32_t, 1>,
///             fern::MaskedArray<int32_t, 1>,
///             fern::MaskedArray<bool, 1>,
///             fern::binary::DiscardDomainErrors,
///             fern::binary::DiscardRangeErrors,
///             InputNoDataPolicy,
///             OutputNoDataPolicy>(
///                 InputNoDataPolicy(result.mask(), true),
///                 OutputNoDataPolicy(result.mask(), true),
///                 array1, array2, result);
///         BOOST_CHECK_EQUAL(result.mask()[0], false);
///         BOOST_CHECK_EQUAL(result.mask()[1], false);
///         BOOST_CHECK_EQUAL(result.mask()[2], true);
///         BOOST_CHECK_EQUAL(result[0], true);
///         BOOST_CHECK_EQUAL(result[1], false);
///         BOOST_CHECK_EQUAL(result[2], false);  // <-- Not touched.
///
///         // Mask the whole input. Result must be masked too.
///         result.mask_all();
///         fern::algebra::equal<
///             fern::MaskedArray<int32_t, 1>,
///             fern::MaskedArray<int32_t, 1>,
///             fern::MaskedArray<bool, 1>,
///             fern::binary::DiscardDomainErrors,
///             fern::binary::DiscardRangeErrors,
///             InputNoDataPolicy,
///             OutputNoDataPolicy>(
///                 InputNoDataPolicy(result.mask(), true),
///                 OutputNoDataPolicy(result.mask(), true),
///                 array1, array2, result);
///         BOOST_CHECK_EQUAL(result.mask()[0], true);
///         BOOST_CHECK_EQUAL(result.mask()[1], true);
///         BOOST_CHECK_EQUAL(result.mask()[2], true);
///     }
///
///     // empty
///     {
///         fern::MaskedArray<int32_t, 1> empty_array;
///         fern::MaskedArray<bool, 1> result;
///         fern::algebra::equal<
///             fern::MaskedArray<int32_t, 1>,
///             fern::MaskedArray<int32_t, 1>,
///             fern::MaskedArray<bool, 1>,
///             fern::binary::DiscardDomainErrors,
///             fern::binary::DiscardRangeErrors,
///             InputNoDataPolicy,
///             OutputNoDataPolicy>(
///                 InputNoDataPolicy(result.mask(), true),
///                 OutputNoDataPolicy(result.mask(), true),
///                 empty_array, empty_array, result);
///         BOOST_CHECK(result.empty());
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(d2_array_d2_array)
/// {
///     // 2d array
///     {
///         fern::Array<int8_t, 2> array1{
///             { -2, -1 },
///             {  0,  9 },
///             {  1,  2 }
///         };
///         fern::Array<int8_t, 2> array2{
///             { -2, -1 },
///             {  5,  9 },
///             {  1,  2 }
///         };
///         fern::Array<bool, 2> result{
///             { false, false },
///             { false, false },
///             { false, false }
///         };
///         fern::algebra::equal(array1, array2, result);
///         BOOST_CHECK_EQUAL(result[0][0], true);
///         BOOST_CHECK_EQUAL(result[0][1], true);
///         BOOST_CHECK_EQUAL(result[1][0], false);
///         BOOST_CHECK_EQUAL(result[1][1], true);
///         BOOST_CHECK_EQUAL(result[2][0], true);
///         BOOST_CHECK_EQUAL(result[2][1], true);
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(masked_d2_array_d2_array)
/// {
///     fern::MaskedArray<int8_t, 2> array1{
///         { -2, -1 },
///         {  0,  9 },
///         {  1,  2 }
///     };
///     fern::MaskedArray<int8_t, 2> array2{
///         { -2, -1 },
///         {  5,  9 },
///         {  1,  2 }
///     };
///
///     // 2d masked array with non-masking equal
///     {
///         fern::MaskedArray<bool, 2> result{
///             { true, true },
///             { true, true },
///             { true, true }
///         };
///         fern::algebra::equal(array1, array2, result);
///         BOOST_CHECK_EQUAL(result[0][0], true);
///         BOOST_CHECK_EQUAL(result[0][1], true);
///         BOOST_CHECK_EQUAL(result[1][0], false);
///         BOOST_CHECK_EQUAL(result[1][1], true);
///         BOOST_CHECK_EQUAL(result[2][0], true);
///         BOOST_CHECK_EQUAL(result[2][1], true);
///     }
///
///     // 2d masked arrays with masking equal
///     {
///         // TODO
///     }
/// }
///
///
/// BOOST_AUTO_TEST_CASE(concurrent)
/// {
///     // Create a somewhat larger array.
///     size_t const nr_rows = 6000;
///     size_t const nr_cols = 4000;
///     auto const extents = fern::extents[nr_rows][nr_cols];
///     fern::Array<int32_t, 2> array1(extents);
///     fern::Array<int32_t, 2> array2(extents);
///     fern::Array<bool, 2> result(extents);
///     fern::algebra::Equal<
///         fern::Array<int32_t, 2>,
///         fern::Array<int32_t, 2>,
///         fern::Array<bool, 2>> equal;
///
///     std::iota(array1.data(), array1.data() + array1.num_elements(), 0);
///     std::iota(array2.data(), array2.data() + array2.num_elements(), 0);
///
///     // Serial.
///     {
///         result.fill(false);
///         fern::serial::execute(equal, array1, array2, result);
///         BOOST_CHECK(std::all_of(result.data(), result.data() +
///             result.num_elements(), [](bool equal){ return equal; }));
///     }
///
///     // Concurrent.
///     {
///         result.fill(false);
///         fern::concurrent::execute(equal, array1, array2, result);
///         BOOST_CHECK(std::all_of(result.data(), result.data() +
///             result.num_elements(), [](bool equal){ return equal; }));
///     }
///
///     {
///         using InputNoDataPolicy = fern::SkipNoData;
///         using OutputNoDataPolicy = fern::MarkNoDataByValue<fern::Mask<2>>;
///
///         fern::MaskedArray<bool, 2> result(extents);
///         fern::algebra::Equal<
///             fern::Array<int32_t, 2>,
///             fern::Array<int32_t, 2>,
///             fern::MaskedArray<bool, 2>,
///             fern::binary::DiscardDomainErrors,
///             fern::binary::DiscardRangeErrors,
///             InputNoDataPolicy,
///             OutputNoDataPolicy> equal(
///                 InputNoDataPolicy(),
///                 OutputNoDataPolicy(result.mask(), true));
///
///         // Verify executor can handle masked result.
///         fern::concurrent::execute(equal, array1, array2, result);
///         BOOST_CHECK(std::all_of(result.data(), result.data() +
///             result.num_elements(), [](bool equal){ return equal; }));
///     }
/// }
///
/// // TODO Test 1d array == 0d array
/// //      Test 2d array == 1d array
/// //      etc

ext: cc

max_stars_repo_name: quanpands/wflow

max_issues_repo_name: quanpands/wflow

max_forks_repo_name: quanpands/wflow


text:
#ifndef GLOBAL_RECONSTRUCTION_ENERGIES_HPP_
#define GLOBAL_RECONSTRUCTION_ENERGIES_HPP_

#include <boost/shared_ptr.hpp>

template<typename DSM, typename NDVI>
class global_reconstruction_unary_energy
{
public:
	typedef double result_type;

	template<typename T>
	result_type operator()(const T &t) const;

	global_reconstruction_unary_energy(
		const DSM& dsm, const NDVI& ndvi,
		double default_energy, double ponderation_dsm, double ndvi_ponderation);

private:
	DSM m_dsm;
	NDVI m_ndvi;
	double m_defaultEnergy;
	double m_ponderation_dsm;
	double m_ponderation_ndvi;
};

#endif /*GLOBAL_RECONSTRUCTION_ENERGIES_HPP_*/


text:
// File: match_utils.cpp
// Author: Francesco Giacomini
// Copyright (c) Members of the EGEE Collaboration. 2009.
// See http://www.eu-egee.org/partners/ for details on the copyright holders.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//     http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// $Id: match_utils.cpp,v 1.1.2.1.4.1 2009/06/18 08:33:29 fcapanni Exp $

#include "match_utils.h"
#include <cmath>
#include <functional>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/regex.hpp>
#include <boost/thread/xtime.hpp>
#include <classad_distribution.h>
#include "glite/wmsutils/classads/classad_utils.h"

namespace ca = glite::wmsutils::classads;

namespace glite {
namespace wms {
namespace manager {
namespace server {

template<typename Container, typename T>
T variance(Container const& c, T mean)
{
  T v = T();
  size_t n = 0;
  typename Container::const_iterator first = c.begin();
  typename Container::const_iterator const last = c.end();
  for ( ; first != last; ++first, ++n) {
    T t = *first - mean;
    v += t * t;
  }

  return n ? v / n : v;
}

class rank_greater_than
  : public std::unary_function<match_type, bool>
{
  double m_rank;
public:
  rank_greater_than(double rank)
    : m_rank(rank)
  {
  }
  bool operator()(match_type const& match)
  {
    return match.get<1>() > m_rank;
  }
};

class rank_less_than
  : public std::unary_function<match_type, bool>
{
  double m_rank;
public:
  rank_less_than(double rank)
    : m_rank(rank)
  {
  }
  bool operator()(match_type const& match)
  {
    return match.get<1>() < m_rank;
  }
};

matches_type::const_iterator
select_best_ce_max_rank(matches_type const& matches)
{
  assert(!matches.empty());
  matches_type::const_iterator const begin(matches.begin());

  double max_rank = begin->get<1>();
  matches_type::const_iterator it(
    find_if(begin, matches.end(), rank_less_than(max_rank))
  );

  boost::xtime current;
  boost::xtime_get(&current, boost::TIME_UTC);
  boost::minstd_rand generator(static_cast<unsigned int>(current.nsec));
  boost::uniform_smallint<size_t> distrib(0, distance(begin, it) - 1);
  boost::variate_generator<
    boost::minstd_rand,
    boost::uniform_smallint<size_t>
    > rand(generator, distrib);

  return begin + rand();
}

double get_p(double sum)
{
  boost::minstd_rand dist(std::time(0));
  boost::uniform_01<boost::minstd_rand> rand(dist);
  return rand() * sum;
}

matches_type::const_iterator
select_best_ce_stochastic(matches_type const& matches)
{
  assert(!matches.empty());

  std::vector<double> ranks;
  ranks.reserve(matches.size());
  double rank_sum = 0.;
  matches_type::const_iterator b = matches.begin();
  matches_type::const_iterator e = matches.end();
  for (; b != e; ++b) {
    double r = b->get<1>();
    ranks.push_back(r);
    rank_sum += r;
  }
  double rank_mean     = rank_sum / ranks.size();
  double rank_variance = variance(ranks, rank_mean);
  // We smooth rank values according to the following function:
  // f(x) = atan( V * (x - mean ) / dev ) + PI
  // Thanks to Alessio Gianelle for his usefull support and suggestions.
  static const double PI = std::atan(1.) * 4.;
  static const double V = PI;
  // Computing the variance and standard deviation of rank samples...
  double rank_deviation = rank_variance > 0 ? sqrt(rank_variance) : V;

  rank_sum = 0.;
  for (size_t r = 0; r < ranks.size(); ++r) {
    ranks[r] = atan(V * (ranks[r] - rank_mean) / rank_deviation) + PI;
    rank_sum += ranks[r];
  }

  boost::xtime current;
  boost::xtime_get(&current, boost::TIME_UTC);
  boost::minstd_rand generator(static_cast<unsigned int>(current.nsec));
  boost::uniform_01<boost::minstd_rand> rand(generator);
  double const p = rand() * rank_sum;

  double prob_sum = 0.;
  size_t i = 0;
  matches_type::const_iterator best = matches.begin();
  matches_type::const_iterator const matches_end = matches.end();
  do {
    prob_sum += ranks[i++];
    if (p < prob_sum) {
      break;
    }
  } while (++best != matches_end);

  return best;
}

matches_type::const_iterator
select_best_ce(matches_type const& matches, bool use_fuzzy_rank)
{
  assert(!matches.empty());

  if (use_fuzzy_rank) {
    return select_best_ce_stochastic(matches);
  } else {
    return select_best_ce_max_rank(matches);
  }
}

bool
fill_matches(
  classad::ClassAd const& match_response,
  matches_type& matches,
  bool include_brokerinfo,
  bool include_cream_resources
)
try {

  std::string reason(ca::evaluate_attribute(match_response, "reason"));
  if (reason != "ok") {
    throw MatchError(reason);
  }

  classad::ExprList const* const match_result(
    ca::evaluate_attribute(match_response, "match_result")
  );

  classad::ExprList::const_iterator it = match_result->begin();
  classad::ExprList::const_iterator const end = match_result->end();
  for ( ; it != end; ++it) {
    assert(ca::is_classad(*it));
    classad::ClassAd const& match(*static_cast<classad::ClassAd const*>(*it));

    std::string const ce_id(ca::evaluate_attribute(match, "ce_id"));
    {
      // if the ce is cream-based ignore it, because dagman is not able to
      // manage it
      static boost::regex const re(".+/([^-]+)-.+");
      boost::smatch pieces;
      std::string base;
      if (boost::regex_match(ce_id, pieces, re)) {
        base.assign(pieces[1].first, pieces[1].second);
      }
      if (base.empty() || (include_cream_resources==false && base == "cream")) {
        continue;
      }
    }
    double rank(ca::evaluate_attribute(match, "rank"));
    ClassAdPtr ad_ptr;
    if (include_brokerinfo) {
      classad::ClassAd const* brokerinfo(
        ca::evaluate_attribute(match, "brokerinfo")
      );
      ad_ptr.reset(static_cast<classad::ClassAd*>(brokerinfo->Copy()));
    }
    matches.push_back(
      boost::make_tuple(ce_id, rank, ad_ptr)
    );
  }

  return !matches.empty();

} catch (ca::InvalidValue&) {
  throw MatchError(
    "invalid format: " + ca::unparse_classad(match_response)
  );
}

}}}} // glite::wms::manager::server

ext: cpp

max_stars_repo_name: italiangrid/wms

max_issues_repo_name: italiangrid/wms

max_forks_repo_name: italiangrid/wms


text:
/*
// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include "ChassisIntrusionSensor.hpp"

#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <thread>

extern "C"
{
#include <i2c/smbus.h>
#include <linux/i2c-dev.h>
}

static constexpr bool DEBUG = false;

static constexpr unsigned int intrusionSensorPollSec = 1;

// SMLink Status Register
const static constexpr size_t pchStatusRegIntrusion = 0x04;

// Status bit field masks
const static constexpr size_t pchRegMaskIntrusion = 0x01;

void ChassisIntrusionSensor::updateValue(const std::string newValue)
{
    // Take no action if value already equal
    // Same semantics as Sensor::updateValue(const double&)
    if (newValue == mValue)
    {
        return;
    }

    // indicate that it is internal set call
    mInternalSet = true;
    mIface->set_property("Status", newValue);
    mInternalSet = false;

    mValue = newValue;

    if (mOldValue == "Normal" && mValue != "Normal")
    {
        std::cerr << "save to SEL for intrusion assert event \n";
        // TODO: call add SEL log API, depends on patch #13956
        mOldValue = mValue;
    }
    else if (mOldValue != "Normal" && mValue == "Normal")
    {
        std::cerr << "save to SEL for intrusion de-assert event \n";
        // TODO: call add SEL log API, depends on patch #13956
        mOldValue = mValue;
    }
}

int ChassisIntrusionSensor::i2cReadFromPch(int busId, int slaveAddr)
{
    std::string i2cBus = "/dev/i2c-" + std::to_string(busId);

    int fd = open(i2cBus.c_str(), O_RDWR | O_CLOEXEC);
    if (fd < 0)
    {
        std::cerr << "unable to open i2c device \n";
        return -1;
    }
    if (ioctl(fd, I2C_SLAVE_FORCE, slaveAddr) < 0)
    {
        std::cerr << "unable to set device address\n";
        close(fd);
        return -1;
    }

    unsigned long funcs = 0;
    if (ioctl(fd, I2C_FUNCS, &funcs) < 0)
    {
        std::cerr << "not support I2C_FUNCS \n";
        close(fd);
        return -1;
    }

    if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA))
    {
        std::cerr << "not support I2C_FUNC_SMBUS_READ_BYTE_DATA \n";
        close(fd);
        return -1;
    }

    int statusValue;
    unsigned int statusMask = pchRegMaskIntrusion;
    unsigned int statusReg = pchStatusRegIntrusion;

    statusValue = i2c_smbus_read_byte_data(fd, statusReg);
    if (DEBUG)
    {
        std::cout << "\nRead bus " << busId << " addr " << slaveAddr
                  << ", value = " << statusValue << "\n";
    }

    close(fd);

    if (statusValue < 0)
    {
        std::cerr << "i2c_smbus_read_byte_data failed \n";
        return -1;
    }

    // Get status value with mask
    int newValue = statusValue & statusMask;

    if (DEBUG)
    {
        std::cout << "statusValue is " << statusValue << "\n";
        std::cout << "Intrusion sensor value is " << newValue << "\n";
    }

    return newValue;
}

void ChassisIntrusionSensor::pollSensorStatusByPch()
{
    // setting a new experation implicitly cancels any pending async wait
    mPollTimer.expires_from_now(
        boost::posix_time::seconds(intrusionSensorPollSec));

    mPollTimer.async_wait([&](const boost::system::error_code& ec) {
        // case of timer expired
        if (!ec)
        {
            int statusValue = i2cReadFromPch(mBusId, mSlaveAddr);
            std::string newValue = statusValue ? "HardwareIntrusion" : "Normal";

            if (newValue != "unknown" && mValue != newValue)
            {
                std::cout << "update value from " << mValue << " to "
                          << newValue << "\n";
                updateValue(newValue);
            }

            // trigger next polling
            pollSensorStatusByPch();
        }
        // case of being canceled
        else if (ec == boost::asio::error::operation_aborted)
        {
            std::cerr << "Timer of intrusion sensor is cancelled. Return \n";
            return;
        }
    });
}

void ChassisIntrusionSensor::readGpio()
{
    mGpioLine.event_read();
    auto value = mGpioLine.get_value();

    // set string defined in chassis redfish schema
    std::string newValue = value ? "HardwareIntrusion" : "Normal";

    if (DEBUG)
    {
        std::cout << "\nGPIO value is " << value << "\n";
        std::cout << "Intrusion sensor value is " << newValue << "\n";
    }

    if (newValue != "unknown" && mValue != newValue)
    {
        std::cout << "update value from " << mValue << " to " << newValue
                  << "\n";
        updateValue(newValue);
    }
}

void ChassisIntrusionSensor::pollSensorStatusByGpio(void)
{
    mGpioFd.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [this](const boost::system::error_code& ec) {
            if (ec == boost::system::errc::bad_file_descriptor)
            {
                return; // we're being destroyed
            }
            else if (ec)
            {
                std::cerr
                    << "Error on GPIO based intrusion sensor wait event\n";
            }
            else
            {
                readGpio();
            }
            pollSensorStatusByGpio();
        });
}

void ChassisIntrusionSensor::initGpioDeviceFile()
{
    mGpioLine = gpiod::find_line(mPinName);
    if (!mGpioLine)
    {
        std::cerr << "ChassisIntrusionSensor error finding gpio pin name: "
                  << mPinName << "\n";
        return;
    }

    try
    {

        mGpioLine.request(
            {"ChassisIntrusionSensor", gpiod::line_request::EVENT_BOTH_EDGES,
             mGpioInverted ? gpiod::line_request::FLAG_ACTIVE_LOW : 0});

        // set string defined in chassis redfish schema
        auto value = mGpioLine.get_value();
        std::string newValue = value ? "HardwareIntrusion" : "Normal";
        updateValue(newValue);

        auto gpioLineFd = mGpioLine.event_get_fd();
        if (gpioLineFd < 0)
        {
            std::cerr << "ChassisIntrusionSensor failed to get " << mPinName
                      << " fd\n";
            return;
        }

        mGpioFd.assign(gpioLineFd);
    }
    catch (std::system_error&)
    {
        std::cerr << "ChassisInrtusionSensor error requesting gpio pin name: "
                  << mPinName << "\n";
        return;
    }
}

int ChassisIntrusionSensor::setSensorValue(const std::string& req,
                                           std::string& propertyValue)
{
    if (!mInternalSet)
    {
        propertyValue = req;
        mOverridenState = true;
    }
    else if (!mOverridenState)
    {
        propertyValue = req;
    }
    return 1;
}

void ChassisIntrusionSensor::start(IntrusionSensorType type, int busId,
                                   int slaveAddr, bool gpioInverted)
{
    if (DEBUG)
    {
        std::cerr << "enter ChassisIntrusionSensor::start, type = " << type
                  << "\n";
        if (type == IntrusionSensorType::pch)
        {
            std::cerr << "busId = " << busId << ", slaveAddr = " << slaveAddr
                      << "\n";
        }
        else if (type == IntrusionSensorType::gpio)
        {
            std::cerr << "gpio pinName = " << mPinName
                      << ", gpioInverted = " << gpioInverted << "\n";
        }
    }

    if ((type == IntrusionSensorType::pch && busId == mBusId &&
         slaveAddr == mSlaveAddr) ||
        (type == IntrusionSensorType::gpio && gpioInverted == mGpioInverted &&
         mInitialized))
    {
        return;
    }

    mType = type;
    mBusId = busId;
    mSlaveAddr = slaveAddr;
    mGpioInverted = gpioInverted;

    if ((mType == IntrusionSensorType::pch && mBusId > 0 && mSlaveAddr > 0) ||
        (mType == IntrusionSensorType::gpio))
    {
        // initialize first if not initialized before
        if (!mInitialized)
        {
            mIface->register_property(
                "Status", mValue,
                [&](const std::string& req, std::string& propertyValue) {
                    return setSensorValue(req, propertyValue);
                });
            mIface->initialize();

            if (mType == IntrusionSensorType::gpio)
            {
                initGpioDeviceFile();
            }

            mInitialized = true;
        }

        // start polling value
        if (mType == IntrusionSensorType::pch)
        {
            pollSensorStatusByPch();
        }
        else if (mType == IntrusionSensorType::gpio && mGpioLine)
        {
            std::cerr << "Start polling intrusion sensors\n";
            pollSensorStatusByGpio();
        }
    }

    // invalid para, release resource
    else
    {
        if (mInitialized)
        {
            if (mType == IntrusionSensorType::pch)
            {
                mPollTimer.cancel();
            }
            else if (mType == IntrusionSensorType::gpio)
            {
                mGpioFd.close();
                if (mGpioLine)
                {
                    mGpioLine.release();
                }
            }
            mInitialized = false;
        }
    }
}

ChassisIntrusionSensor::ChassisIntrusionSensor(
    boost::asio::io_service& io,
    std::shared_ptr<sdbusplus::asio::dbus_interface> iface) :
    mIface(iface),
    mType(IntrusionSensorType::gpio), mValue("unknown"), mOldValue("unknown"),
    mBusId(-1), mSlaveAddr(-1), mPollTimer(io), mGpioInverted(false),
    mGpioFd(io)
{}

ChassisIntrusionSensor::~ChassisIntrusionSensor()
{
    if (mType == IntrusionSensorType::pch)
    {
        mPollTimer.cancel();
    }
    else if (mType == IntrusionSensorType::gpio)
    {
        mGpioFd.close();
        if (mGpioLine)
        {
            mGpioLine.release();
        }
    }
}


text:
#include "ChipConfig.hpp"
#include "Bitstream.hpp"
#include "Chip.hpp"
#include "Database.hpp"
#include "DatabasePath.hpp"
#include "version.hpp"
#include "wasmexcept.hpp"
#include <iostream>
#include <boost/optional.hpp>
#include <boost/program_options.hpp>
#include <stdexcept>
#include <streambuf>
#include <fstream>

using namespace std;

int main(int argc, char *argv[])
{
    using namespace Trellis;
    namespace po = boost::program_options;
    boost::optional<uint32_t> idcode;

    std::string database_folder = get_database_path();

    po::options_description options("Allowed options");
    options.add_options()("help,h", "show help");
    options.add_options()("verbose,v", "verbose output");
    options.add_options()("db", po::value<std::string>(), "Trellis database folder location");
    options.add_options()("idcode", po::value<std::string>(), "IDCODE to override in bitstream");
    po::positional_options_description pos;
    options.add_options()("input", po::value<std::string>()->required(), "input bitstream file");
    pos.add("input", 1);
    options.add_options()("textcfg", po::value<std::string>()->required(), "output textual configuration");
    pos.add("textcfg", 1);

    po::variables_map vm;
    try {
        po::parsed_options parsed = po::command_line_parser(argc, argv).options(options).positional(pos).run();
        po::store(parsed, vm);
        po::notify(vm);
    }
    catch (po::required_option &e) {
        cerr << "Error: input file is mandatory." << endl << endl;
        goto help;
    }
    catch (std::exception &e) {
        cerr << "Error: " << e.what() << endl << endl;
        goto help;
    }

    if (vm.count("help")) {
help:
        cerr << "Project Trellis - Open Source Tools for ECP5 FPGAs" << endl;
        cerr << "Version " << git_describe_str << endl;
        cerr << argv[0] << ": ECP5 bitstream to text config converter" << endl;
        cerr << endl;
        cerr << "Copyright (C) 2018 David Shah <david@symbioticeda.com>" << endl;
        cerr << endl;
        cerr << "Usage: " << argv[0] << " input.bit [output.config] [options]" << endl;
        cerr << options << endl;
        return vm.count("help") ? 0 : 1;
    }

    ifstream bit_file(vm["input"].as<string>(), ios::binary);
    if (!bit_file) {
        cerr << "Failed to open input file" << endl;
        return 1;
    }

    if (vm.count("db")) {
        database_folder = vm["db"].as<string>();
    }

    if (vm.count("idcode")) {
        string idcode_str = vm["idcode"].as<string>();
        uint32_t idcode_val;
        idcode_val = uint32_t(strtoul(idcode_str.c_str(), nullptr, 0));
        if (idcode_val == 0) {
            cerr << "Invalid idcode: " << idcode_str << endl;
            return 1;
        }
        idcode = idcode_val;
    }

    try {
        load_database(database_folder);
    } catch (runtime_error &e) {
        cerr << "Failed to load Trellis database: " << e.what() << endl;
        return 1;
    }

    try {
        Chip c = Bitstream::read_bit(bit_file).deserialise_chip(idcode);
        ChipConfig cc = ChipConfig::from_chip(c);
        ofstream out_file(vm["textcfg"].as<string>());
        if (!out_file) {
            cerr << "Failed to open output file" << endl;
            return 1;
        }
        out_file << cc.to_string();
        return 0;
    } catch (BitstreamParseError &e) {
        cerr << "Failed to process input bitstream: " << e.what() << endl;
        return 1;
    } catch (runtime_error &e) {
        cerr << "Failed to process input bitstream: " << e.what() << endl;
        return 1;
    }

}

max_stars_repo_name: umarcor/prjtrellis

max_issues_repo_name: umarcor/prjtrellis

max_forks_repo_name: umarcor/prjtrellis


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

#include <iostream>

#include <boost/filesystem.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>

#include "BoVW/bow_trainer.h"

void getFilenames(const std::string& directory,
                  std::vector<std::string>* filenames) {
    using namespace boost::filesystem;

    filenames->clear();
    path dir(directory);

    // Retrieving, sorting and filtering filenames.
    std::vector<path> entries;
    copy(directory_iterator(dir), directory_iterator(), back_inserter(entries));
    sort(entries.begin(), entries.end());
    for (auto it = entries.begin(); it != entries.end(); it++) {
        std::string ext = it->extension().c_str();
        std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);

        if (ext == ".png" || ext == ".jpg" ||
            ext == ".ppm" || ext == ".jpeg") {
            filenames->push_back(it->string());
        }
    }
}

int main(int argc, char** argv) {
  // Creating feature detector and descriptor
  cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create();
  // surf->setMinHessian(400);

  // Loading image filenames
  std::vector<std::string> filenames;
  getFilenames(argv[1], &filenames);
  unsigned nimages = filenames.size();

  // BoW Trainer
  bovw::BoVWTrainer bow_trainer;

  // Processing the sequence of images
  for (unsigned i = 0; i < 5; i++) {
    // Processing image i
    std::cout << "--- Processing image " << i << std::endl;

    // Loading and describing the image
    cv::Mat img = cv::imread(filenames[i]);
    std::vector<cv::KeyPoint> kps;
    surf->detect(img, kps);
    cv::Mat dscs;
    surf->compute(img, kps, dscs);

    // cv::Mat out;
    // cv::drawKeypoints(img, kps, out);

    // cv::imshow("Out", out);
    // cv::waitKey(5);

    bow_trainer.add(i, dscs);
  }

  // Training
  cv::Mat vwords, idf;
  bow_trainer.train(vwords, idf, 100);

  return 0;
}

max_stars_repo_name: emiliofidalgo/BoVW

max_issues_repo_name: emiliofidalgo/BoVW

max_forks_repo_name: emiliofidalgo/BoVW