text:
#include <pxp-agent/external_module.hpp>
#include <pxp-agent/module_type.hpp>
#include <pxp-agent/action_output.hpp>
#include <pxp-agent/configuration.hpp>

#include <leatherman/execution/execution.hpp>

#include <leatherman/file_util/file.hpp>

#include <leatherman/locale/locale.hpp>

#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.pxp_agent.external_module"
#include <leatherman/logging/logging.hpp>

#include <cpp-pcp-client/util/thread.hpp>   // this_thread::sleep_for
#include <cpp-pcp-client/util/chrono.hpp>

#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>

#include <atomic>
#include <memory>   // std::shared_ptr
#include <utility>  // std::move

// TODO(ale): disable assert() once we're confident with the code...
// To disable assert()
// #define NDEBUG
#include <cassert>

namespace PXPAgent {

static const std::string METADATA_SCHEMA_NAME { "external_module_metadata" };
static const std::string ACTION_SCHEMA_NAME { "action_metadata" };

static const std::string METADATA_CONFIGURATION_ENTRY { "configuration" };
static const std::string METADATA_ACTIONS_ENTRY { "actions" };

static const int EXTERNAL_MODULE_FILE_ERROR_EC { 5 };

namespace fs = boost::filesystem;
namespace lth_exec = leatherman::execution;
namespace lth_file = leatherman::file_util;
namespace lth_jc   = leatherman::json_container;
namespace lth_loc  = leatherman::locale;
namespace pcp_util = PCPClient::Util;

//
// Free functions
//

// Provides the module metadata validator
PCPClient::Validator getMetadataValidator()
{
    // Metadata schema
    PCPClient::Schema metadata_schema { METADATA_SCHEMA_NAME,
                                          PCPClient::ContentType::Json };
    using T_C = PCPClient::TypeConstraint;
    metadata_schema.addConstraint("description", T_C::String, true);
    metadata_schema.addConstraint(METADATA_CONFIGURATION_ENTRY, T_C::Object, false);
    metadata_schema.addConstraint(METADATA_ACTIONS_ENTRY, T_C::Array, true);

    // 'actions' is an array of actions; define the action sub_schema
    PCPClient::Schema action_schema { ACTION_SCHEMA_NAME,
                                      PCPClient::ContentType::Json };
    action_schema.addConstraint("description", T_C::String, false);
    action_schema.addConstraint("name", T_C::String, true);
    action_schema.addConstraint("input", T_C::Object, true);
    action_schema.addConstraint("results", T_C::Object, true);

    metadata_schema.addConstraint(METADATA_ACTIONS_ENTRY, action_schema, false);

    PCPClient::Validator validator {};
    validator.registerSchema(metadata_schema);
    return validator;
}

//
// Public interface
//

ExternalModule::ExternalModule(const std::string& path,
                               const lth_jc::JsonContainer& config,
                               std::shared_ptr<ResultsStorage> storage)
        : path_ { path },
          config_ { config },
          storage_ { std::move(storage) }
{
    fs::path module_path { path };
    module_name = module_path.stem().string();
    auto metadata = getModuleMetadata();

    try {
        if (metadata.includes(METADATA_CONFIGURATION_ENTRY)) {
            registerConfiguration(
                metadata.get<lth_jc::JsonContainer>(METADATA_CONFIGURATION_ENTRY));
        } else {
            LOG_DEBUG("Found no configuration schema for module '{1}'", module_name);
        }

        registerActions(metadata);
    } catch (lth_jc::data_error& e) {
        LOG_ERROR("Failed to retrieve metadata of module {1}: {2}",
                  module_name, e.what());
        throw Module::LoadingError {
            lth_loc::format("invalid metadata of module {1}", module_name) };
    }
}

ExternalModule::ExternalModule(const std::string& path,
                               std::shared_ptr<ResultsStorage> storage)
        : path_ { path },
          config_ { "{}" },
          storage_ { std::move(storage) }
{
    fs::path module_path { path };
    module_name = module_path.stem().string();
    auto metadata = getModuleMetadata();

    try {
       registerActions(metadata);
    } catch (lth_jc::data_error& e) {
        LOG_ERROR("Failed to retrieve metadata of module {1}: {2}",
                  module_name, e.what());
        throw Module::LoadingError {
            lth_loc::format("invalid metadata of module {1}", module_name) };
    }
}

void ExternalModule::validateConfiguration()
{
    if (config_validator_.includesSchema(module_name)) {
        config_validator_.validate(config_, module_name);
    } else {
        LOG_DEBUG("The '{1}' configuration will not be validated; no JSON "
                  "schema is available", module_name);
    }
}

//
// Static class members
//

// cppcheck-suppress constStatement
const int ExternalModule::OUTPUT_DELAY_MS { 100 };

void ExternalModule::processOutputAndUpdateMetadata(ActionResponse& response)
{
    if (response.output.std_out.empty()) {
        LOG_TRACE("Obtained no results on stdout for the {1}",
                  response.prettyRequestLabel());
    } else {
        LOG_TRACE("Results on stdout for the {1}: {2}",
                  response.prettyRequestLabel(), response.output.std_out);
    }

    if (response.output.exitcode != EXIT_SUCCESS) {
        LOG_TRACE("Execution failure (exit code {1}) for the {2}{3}",
                  response.output.exitcode, response.prettyRequestLabel(),
                  (response.output.std_err.empty()
                        ? ""
                        : "; stderr:\n" + response.output.std_err));
    } else if (!response.output.std_err.empty()) {
        LOG_TRACE("Output on stderr for the {1}:\n{2}",
                  response.prettyRequestLabel(), response.output.std_err);
    }

    try {
        // Ensure output format is valid JSON by instantiating
        // JsonContainer (NB: its ctor does not accept empty strings)
        lth_jc::JsonContainer results {
            (response.output.std_out.empty() ? "null" : response.output.std_out) };
        response.setValidResultsAndEnd(std::move(results));
    } catch (lth_jc::data_parse_error& e) {
        LOG_DEBUG("Obtained invalid JSON on stdout for the {1}; (validation "
                  "error: {2}); stdout:\n{3}",
                  response.prettyRequestLabel(), e.what(), response.output.std_out);
        std::string execution_error {
            lth_loc::format("The task executed for the {1} returned invalid "
                            "JSON on stdout - stderr:{2}",
                            response.prettyRequestLabel(),
                            (response.output.std_err.empty()
                                ? lth_loc::translate(" (empty)")
                                : "\n" + response.output.std_err)) };
        response.setBadResultsAndEnd(execution_error);
    }
}

//
// Private interface
//

// Metadata validator (static member)
const PCPClient::Validator ExternalModule::metadata_validator_ {
        getMetadataValidator() };

// Retrieve and validate the module's metadata
const lth_jc::JsonContainer ExternalModule::getModuleMetadata()
{
    auto exec = lth_exec::execute(
#ifdef _WIN32
        "cmd.exe", { "/c", path_, "metadata" },
#else
        path_, { "metadata" },
#endif
        0,  // timeout
        { lth_exec::execution_options::thread_safe,
          lth_exec::execution_options::merge_environment,
          lth_exec::execution_options::inherit_locale });  // options

    if (!exec.error.empty()) {
        LOG_ERROR("Failed to load the external module metadata from {1}: {2}",
                  path_, exec.error);
        throw Module::LoadingError {
            lth_loc::translate("failed to load external module metadata") };
    }

    lth_jc::JsonContainer metadata;

    try {
        metadata = lth_jc::JsonContainer { exec.output };
        LOG_DEBUG("External module {1}: metadata is valid JSON", module_name);
    } catch (lth_jc::data_error& e) {
        throw Module::LoadingError {
            lth_loc::format("metadata is not in a valid JSON format: {1}", e.what()) };
    }

    try {
        metadata_validator_.validate(metadata, METADATA_SCHEMA_NAME);
        LOG_DEBUG("External module {1}: metadata validation OK", module_name);
    } catch (PCPClient::validation_error& e) {
        throw Module::LoadingError {
            lth_loc::format("metadata validation failure: {1}", e.what()) };
    }

    return metadata;
}

void ExternalModule::registerConfiguration(const lth_jc::JsonContainer& config_metadata)
{
    try {
        PCPClient::Schema configuration_schema { module_name, config_metadata };
        LOG_DEBUG("Registering module configuration schema for '{1}'", module_name);
        config_validator_.registerSchema(configuration_schema);
    } catch (PCPClient::schema_error& e) {
        LOG_ERROR("Failed to parse the configuration schema of module '{1}': {2}",
                  module_name, e.what());
        throw Module::LoadingError {
            lth_loc::format("invalid configuration schema of module {1}", module_name) };
    }
}

void ExternalModule::registerActions(const lth_jc::JsonContainer& metadata)
{
    for (auto& action
            : metadata.get<std::vector<lth_jc::JsonContainer>>(METADATA_ACTIONS_ENTRY))
        registerAction(action);
}

// Register the specified action after ensuring that the input and
// output schemas are valid JSON (i.e. we can instantiate Schema).
void ExternalModule::registerAction(const lth_jc::JsonContainer& action)
{
    // NOTE(ale): name, input, and output are required action entries
    auto action_name = action.get<std::string>("name");
    LOG_DEBUG("Validating action '{1} {2}'", module_name, action_name);

    try {
        auto input_schema_json = action.get<lth_jc::JsonContainer>("input");
        PCPClient::Schema input_schema { action_name, input_schema_json };

        auto results_schema_json = action.get<lth_jc::JsonContainer>("results");
        PCPClient::Schema results_schema { action_name, results_schema_json };

        // Metadata schemas are valid JSON; store metadata
        LOG_DEBUG("Action '{1} {2}' has been validated", module_name, action_name);
        actions.push_back(action_name);
        input_validator_.registerSchema(input_schema);
        results_validator_.registerSchema(results_schema);
    } catch (PCPClient::schema_error& e) {
        LOG_ERROR("Failed to parse metadata schemas of action '{1} {2}': {3}",
                  module_name, action_name, e.what());
        throw Module::LoadingError {
            lth_loc::format("invalid schemas of '{1} {2}'", module_name, action_name) };
    } catch (lth_jc::data_error& e) {
        LOG_ERROR("Failed to retrieve metadata schemas of action '{1} {2}': {3}",
                  module_name, action_name, e.what());
        throw Module::LoadingError {
            lth_loc::format("invalid metadata of '{1} {2}'", module_name, action_name) };
    }
}

std::string ExternalModule::getActionArguments(const ActionRequest& request)
{
    lth_jc::JsonContainer action_args {};
    action_args.set<lth_jc::JsonContainer>("input", request.params());

    if (!config_.empty())
        action_args.set<lth_jc::JsonContainer>("configuration", config_);

    if (request.type() == RequestType::NonBlocking) {
        fs::path r_d_p { request.resultsDir() };
        lth_jc::JsonContainer output_files {};
        output_files.set<std::string>("stdout", (r_d_p / "stdout").string());
        output_files.set<std::string>("stderr", (r_d_p / "stderr").string());
        output_files.set<std::string>("exitcode", (r_d_p / "exitcode").string());
        action_args.set<lth_jc::JsonContainer>("output_files", output_files);
    }

    return action_args.toString();
}

ActionResponse ExternalModule::callBlockingAction(const ActionRequest& request)
{
    ActionResponse response { ModuleType::External, request };
    auto action_name = request.action();
    auto action_args = getActionArguments(request);

    LOG_INFO("Executing the {1}", request.prettyLabel());
    LOG_TRACE("Input for the {1}: {2}", request.prettyLabel(), action_args);

    auto exec = lth_exec::execute(
#ifdef _WIN32
        "cmd.exe", { "/c", path_, action_name },
#else
        path_, { action_name },
#endif
        action_args,                           // args
        std::map<std::string, std::string>(),  // environment
        0,                                     // timeout
        { lth_exec::execution_options::thread_safe,
          lth_exec::execution_options::merge_environment,
          lth_exec::execution_options::inherit_locale });  // options

    response.output = ActionOutput { exec.exit_code, exec.output, exec.error };
    processOutputAndUpdateMetadata(response);
    return response;
}

ActionResponse ExternalModule::callNonBlockingAction(const ActionRequest& request)
{
    ActionResponse response { ModuleType::External, request };
    auto action_name = request.action();
    auto input_txt = getActionArguments(request);
    fs::path results_dir_path { request.resultsDir() };

    LOG_INFO("Starting a task for the {1}; stdout and stderr will be stored in {2}",
             request.prettyLabel(), request.resultsDir());
    LOG_TRACE("Input for the {1}: {2}", request.prettyLabel(), input_txt);

    // NOTE(ale,mruzicka): to avoid terminating the entire process
    // tree when the pxp-agent service stops, we use the
    // `create_detached_process` execution option which ensures
    // the child process is executed in a new process contract
    // on Solaris and a new process group on Windows

    auto exec = lth_exec::execute(
#ifdef _WIN32
        "cmd.exe", { "/c", path_, action_name },
#else
        path_, { action_name },
#endif
        input_txt,  // input arguments, passed via stdin
        std::map<std::string, std::string>(),  // environment
        [results_dir_path](size_t pid) {
            auto pid_file = (results_dir_path / "pid").string();
            lth_file::atomic_write_to_file(std::to_string(pid) + "\n", pid_file,
                                           NIX_FILE_PERMS, std::ios::binary);
        },          // pid callback
        0,          // timeout
        { lth_exec::execution_options::thread_safe,
          lth_exec::execution_options::create_detached_process,
          lth_exec::execution_options::merge_environment,
          lth_exec::execution_options::inherit_locale });  // options

    LOG_INFO("The execution of the {1} has completed", request.prettyLabel());

    if (exec.exit_code == EXTERNAL_MODULE_FILE_ERROR_EC) {
        // This is unexpected. The output of the task will not be
        // available for future transaction status requests; we cannot
        // provide a reliable ActionResponse.
        std::string empty_label { lth_loc::translate("(empty)") };
        LOG_WARNING("The execution process failed to write output on file for the {1}; "
                    "stdout: {2}; stderr: {3}",
                    request.prettyLabel(),
                    (exec.output.empty() ? empty_label : exec.output),
                    (exec.error.empty() ? empty_label : exec.error));
        throw Module::ProcessingError {
            lth_loc::translate("failed to write output on file") };
    }

    // Wait a bit to relax the requirement for the exitcode file being
    // written before the output ones, when the process completes
    LOG_TRACE("Waiting {1} ms before retrieving the output of {2}",
              OUTPUT_DELAY_MS, request.prettyLabel());
    pcp_util::this_thread::sleep_for(
        pcp_util::chrono::milliseconds(OUTPUT_DELAY_MS));

    // Stdout / stderr output should be on file; read it
    response.output = storage_->getOutput(request.transactionId(), exec.exit_code);
    processOutputAndUpdateMetadata(response);
    return response;
}

ActionResponse ExternalModule::callAction(const ActionRequest& request)
{
    if (request.type() == RequestType::Blocking) {
        return callBlockingAction(request);
    } else {
        // Guranteed by Configuration
        assert(!request.resultsDir().empty());
        return callNonBlockingAction(request);
    }
}

}  // namespace PXPAgent

max_stars_repo_name: Dorin-Pleava/pxp-agent

max_issues_repo_name: Dorin-Pleava/pxp-agent

max_forks_repo_name: Dorin-Pleava/pxp-agent


text:
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2014 Jose Aparicio

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program 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 license for more details.
*/

#ifndef quantlib_tcopula_policy_hpp
#define quantlib_tcopula_policy_hpp

#include <ql/errors.hpp>
#include <ql/utilities/disposable.hpp>
#include <ql/experimental/math/convolvedstudentt.hpp>
#include <boost/math/distributions/students_t.hpp>
#include <boost/bind.hpp>
#include <vector>

namespace QuantLib {

    /*! \brief Student-T Latent Model's copula policy.

    Describes the copula of a set of normalized Student-T independent random
    factors to be fed into the latent variable model.
    The latent model requires the independent variables to be of unit variance
    so the policy expects the factors coefficients to be as usual and the T
    variables to be normalized, the normalization is performed by the policy.
    To normalize the random variables they are divided by the square root of
    the variance of each T (\f$ \frac{\nu}{\nu-2}\f$)
    */
    class TCopulaPolicy {
    public:
        /*! Stores the parameters defining the factors random variable
        T-distributions. As it is now the latent models are restricted to
        having the same distribution for all idiosyncratic factors, so only
        one parameter is needed for them.
        */
        typedef
            struct {
                std::vector<Integer> tOrders;
            } initTraits;

        /*! Delayed initialization of the distribution parameters and caches.
        To be called by the latent model. */
        /* \todo
        Explore other constructors, with different vector dimensions, defining
        simpler combinations (only one correlation, only one variable) might
        simplify memory.
        */
        explicit TCopulaPolicy(
            const std::vector<std::vector<Real> >& factorWeights =
                std::vector<std::vector<Real> >(),
            const initTraits& vals = initTraits());

        //! Number of independent random factors.
        Size numFactors() const {
            return latentVarsInverters_.size() + varianceFactors_.size() - 1;
        }

        //! returns a copy of the initialization arguments
        //... better to have a cache?
        initTraits getInitTraits() const {
            initTraits data;
            data.tOrders.resize(distributions_.size());
            for (Size i=0; i<distributions_.size(); ++i) {
                data.tOrders[i] = static_cast<Integer>(
                    distributions_[i].degrees_of_freedom());
            }
            return data;
        }
        const std::vector<Real>& varianceFactors() const {
            return varianceFactors_;
        }
        /*! Cumulative probability of a given latent variable.
            The iVariable parameter is the index of the requested variable.
        */
        Probability cumulativeY(Real val, Size iVariable) const {
    #if defined(QL_EXTRA_SAFETY_CHECKS)
            QL_REQUIRE(iVariable < latentVarsCumul_.size(),
                "Latent variable index out of bounds.");
    #endif
            return latentVarsCumul_[iVariable](val);
        }
        //! Cumulative probability of the idiosyncratic factors (all the same)
        Probability cumulativeZ(Real z) const {
            return boost::math::cdf(distributions_.back(), z /
                varianceFactors_.back());
        }
        /*! Probability density of a given realization of values of the systemic
          factors (remember they are independent).
          Intended to be used in numerical integration of an arbitrary function
          depending on those values.
        */
        Probability density(const std::vector<Real>& m) const {
    #if defined(QL_EXTRA_SAFETY_CHECKS)
            QL_REQUIRE(m.size() == distributions_.size()-1,
                "Incompatible sample and latent model sizes");
    #endif
            Real prodDensities = 1.;
            for(Size i=0; i<m.size(); i++)
                prodDensities *= boost::math::pdf(distributions_[i],
                    m[i] /varianceFactors_[i]) /varianceFactors_[i];
                 // accumulate lambda
            return prodDensities;
        }
        /*! Returns the inverse of the cumulative distribution of the (modelled)
          latent variable (as indexed by iVariable). Involves the convolution
          of the factors' distributions.
        */
        Real inverseCumulativeY(Probability p, Size iVariable) const {
    #if defined(QL_EXTRA_SAFETY_CHECKS)
            QL_REQUIRE(iVariable < latentVarsCumul_.size(),
                "Latent variable index out of bounds.");
    #endif
            return latentVarsInverters_[iVariable](p);
        }
        /*! Returns the inverse of the cumulative distribution of the
        idiosincratic factor. The LM here is limited to all idiosincratic
        factors following the same distribution.
        */
        Real inverseCumulativeZ(Probability p) const {
            return boost::math::quantile(distributions_.back(), p)
                * varianceFactors_.back();
        }
        /*! Returns the inverse of the cumulative distribution of the
          systemic factor iFactor.
        */
        Real inverseCumulativeDensity(Probability p, Size iFactor) const {
    #if defined(QL_EXTRA_SAFETY_CHECKS)
            QL_REQUIRE(iFactor < distributions_.size()-1,
                "Random factor variable index out of bounds.");
    #endif
            return boost::math::quantile(distributions_[iFactor], p)
                * varianceFactors_[iFactor];
        }
        //to use this (by default) version, the generator must be a uniform one.
        Disposable<std::vector<Real> >
            allFactorCumulInverter(const std::vector<Real>& probs) const;
    private:
        mutable std::vector<boost::math::students_t_distribution<> >
            distributions_;
        mutable std::vector<Real> varianceFactors_;
        mutable std::vector<CumulativeBehrensFisher> latentVarsCumul_;
        mutable std::vector<InverseCumulativeBehrensFisher>
            latentVarsInverters_;
    };

}

#endif

ext: hpp

max_stars_repo_name: grandtiger/quantlib

max_issues_repo_name: grandtiger/quantlib

max_forks_repo_name: grandtiger/quantlib


text:
/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include "poses-precomp.h"  // Precompiled headers

#include <mrpt/poses/CPose2DInterpolator.h>
#include <mrpt/serialization/stl_serialization.h>
#include <Eigen/Dense>
#include "CPoseInterpolatorBase.hpp"  // templ impl

using namespace mrpt::poses;

IMPLEMENTS_SERIALIZABLE(CPose2DInterpolator, CSerializable, mrpt::poses)

uint8_t CPose2DInterpolator::serializeGetVersion() const { return 0; }
void CPose2DInterpolator::serializeTo(mrpt::serialization::CArchive& out) const
{
	out << m_path;
}
void CPose2DInterpolator::serializeFrom(
	mrpt::serialization::CArchive& in, uint8_t version)
{
	switch (version)
	{
		case 0:
		{
			in >> m_path;
		}
		break;
		default:
			MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(version);
	};
}

namespace mrpt::poses
{
// Specialization for DIM=2
template <>
void CPoseInterpolatorBase<2>::impl_interpolation(
	const TTimePosePair& p1, const TTimePosePair& p2, const TTimePosePair& p3,
	const TTimePosePair& p4, const TInterpolatorMethod method,
	const mrpt::Clock::time_point& t, pose_t& out_interp) const
{
	using mrpt::math::TPose2D;
	using doubleDuration = std::chrono::duration<double>;
	doubleDuration durationT(t.time_since_epoch());
	double td = durationT.count();
	mrpt::math::CVectorFixedDouble<4> ts;
	ts[0] =
		std::chrono::duration_cast<doubleDuration>(p1.first.time_since_epoch())
			.count();
	ts[1] =
		std::chrono::duration_cast<doubleDuration>(p2.first.time_since_epoch())
			.count();
	ts[2] =
		std::chrono::duration_cast<doubleDuration>(p3.first.time_since_epoch())
			.count();
	ts[3] =
		std::chrono::duration_cast<doubleDuration>(p4.first.time_since_epoch())
			.count();

	mrpt::math::CVectorFixedDouble<4> X, Y, yaw;
	X[0] = p1.second.x;
	Y[0] = p1.second.y;
	yaw[0] = p1.second.phi;
	X[1] = p2.second.x;
	Y[1] = p2.second.y;
	yaw[1] = p2.second.phi;
	X[2] = p3.second.x;
	Y[2] = p3.second.y;
	yaw[2] = p3.second.phi;
	X[3] = p4.second.x;
	Y[3] = p4.second.y;
	yaw[3] = p4.second.phi;

	unwrap2PiSequence(yaw);

	// Target interpolated values:
	switch (method)
	{
		case imSpline:
		{
			// ---------------------------------------
			//    SPLINE INTERPOLATION
			// ---------------------------------------
			out_interp.x = math::spline(td, ts, X);
			out_interp.y = math::spline(td, ts, Y);
			out_interp.phi = math::spline(td, ts, yaw, true);  // Wrap 2pi
		}
		break;

		case imLinear2Neig:
		{
			out_interp.x =
				math::interpolate2points(td, ts[1], X[1], ts[2], X[2]);
			out_interp.y =
				math::interpolate2points(td, ts[1], Y[1], ts[2], Y[2]);
			out_interp.phi = math::interpolate2points(
				td, ts[1], yaw[1], ts[2], yaw[2], true);  // Wrap 2pi
		}
		break;

		case imLinear4Neig:
		{
			out_interp.x =
				math::leastSquareLinearFit<double, decltype(ts), 4>(td, ts, X);
			out_interp.y =
				math::leastSquareLinearFit<double, decltype(ts), 4>(td, ts, Y);
			out_interp.phi =
				math::leastSquareLinearFit<double, decltype(ts), 4>(
					td, ts, yaw, true);  // Wrap 2pi
		}
		break;

		case imSSLLLL:
		{
			out_interp.x = math::spline(td, ts, X);
			out_interp.y = math::spline(td, ts, Y);
			out_interp.phi =
				math::leastSquareLinearFit<double, decltype(ts), 4>(
					td, ts, yaw, true);  // Wrap 2pi
		}
		break;

		case imSSLSLL:
		{
			out_interp.x = math::spline(td, ts, X);
			out_interp.y = math::spline(td, ts, Y);
			out_interp.phi = math::spline(td, ts, yaw, true);  // Wrap 2pi
		}
		break;

		case imLinearSlerp:
		{
			const double ratio = (td - ts[1]) / (ts[2] - ts[1]);
			const double Aang = mrpt::math::angDistance(yaw[1], yaw[2]);
			out_interp.phi = yaw[1] + ratio * Aang;

			out_interp.x =
				math::interpolate2points(td, ts[1], X[1], ts[2], X[2]);
			out_interp.y =
				math::interpolate2points(td, ts[1], Y[1], ts[2], Y[2]);
		}
		break;

		case imSplineSlerp:
		{
			const double ratio = (td - ts[1]) / (ts[2] - ts[1]);
			const double Aang = mrpt::math::angDistance(yaw[1], yaw[2]);
			out_interp.phi = yaw[1] + ratio * Aang;

			out_interp.x = math::spline(td, ts, X);
			out_interp.y = math::spline(td, ts, Y);
		}
		break;

		default:
			THROW_EXCEPTION("Unknown value for interpolation method!");
	};  // end switch
}

// Explicit instantations:
template class CPoseInterpolatorBase<2>;
}  // namespace mrpt::poses

ext: cpp

max_stars_repo_name: zarmomin/mrpt

max_issues_repo_name: gao-ouyang/mrpt

max_forks_repo_name: gao-ouyang/mrpt


text:
#ifndef GFX_HPP
#define GFX_HPP

#define _USE_MATH_DEFINES
#include <vector>
#include <random>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <Eigen/Core>
#include <Eigen/Geometry>

namespace fox
{
	class counter;
}

class gfx
{
public:

	gfx();

	void init();
	void deinit();
	void render();
	void resize(int w, int h);
	int main_loop();

private:
	void print_info();
	void load_shaders();

	fox::counter *fps_counter;
	fox::counter *update_counter;
	fox::counter *perf_counter;
	SDL_Window *window;
	SDL_GLContext context;
	int done;
	int win_w;
	int win_h;

	/**
	 * @brief Position (x1, x2, x3), two vectors for new and old
	 */
	std::vector<Eigen::Vector3f> x[2];
	/**
	 * @brief Velocity, two vectors for new and old
	 */
	std::vector<Eigen::Vector3f> v[2];
	// TODO: delete a[]
	/**
	 * @brief Acceleration, two vectors for new and old
	 */
	std::vector<Eigen::Vector3f> a[2];
	/**
	 * @brief Object mass
	 */
	std::vector<float> m;

	/**
	 * @brief A random generator that is initialized in the constructor
	 */
	std::mt19937_64 generator;

	double G = 6.67408e-11;
	uint16_t obj_count;

	// an empty vertex array object to bind to
	uint32_t default_vao;
	Eigen::Vector3f eye, target, up;
	Eigen::Affine3f V;
	Eigen::Affine3f M;
	Eigen::Projective3f P, MVP;

	GLuint point_shader_id, shader_vert_id, shader_frag_id, comp_shader_id, comp_prog;
	GLuint x_vbo_0, x_vbo_1, v_vbo_0, v_vbo_1, a_vbo_0, a_vbo_1, m_vbo;

	uint32_t current, next;

	const static uint8_t perf_array_size = 8;
	double phys_times[perf_array_size];
	double render_times[perf_array_size];
	double phys_time;
	double render_time;
	uint8_t perf_index;
	double total_time;
};

#endif


text:
#pragma once
#include <eosio/chain/controller.hpp>
#include <eosio/chain/asset.hpp>
#include <eosio/chain/contract_table_objects.hpp>
#include <eosio/chain/account_object.hpp>
#include <eosio/chain/abi_serializer.hpp>
#include <fc/io/json.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/tuple/tuple_io.hpp>

#include <iosfwd>

#define REQUIRE_EQUAL_OBJECTS(left, right) { auto a = fc::variant( left ); auto b = fc::variant( right ); BOOST_REQUIRE_EQUAL( true, a.is_object() ); \
   BOOST_REQUIRE_EQUAL( true, b.is_object() ); \
   BOOST_REQUIRE_EQUAL_COLLECTIONS( a.get_object().begin(), a.get_object().end(), b.get_object().begin(), b.get_object().end() ); }

#define REQUIRE_MATCHING_OBJECT(left, right) { auto a = fc::variant( left ); auto b = fc::variant( right ); BOOST_REQUIRE_EQUAL( true, a.is_object() ); \
   BOOST_REQUIRE_EQUAL( true, b.is_object() ); \
   auto filtered = ::eosio::testing::filter_fields( a.get_object(), b.get_object() ); \
   BOOST_REQUIRE_EQUAL_COLLECTIONS( a.get_object().begin(), a.get_object().end(), filtered.begin(), filtered.end() ); }

std::ostream& operator<<( std::ostream& osm, const fc::variant& v );

std::ostream& operator<<( std::ostream& osm, const fc::variant_object& v );

std::ostream& operator<<( std::ostream& osm, const fc::variant_object::entry& e );

eosio::chain::asset core_from_string(const std::string& s);

namespace boost { namespace test_tools { namespace tt_detail {

   template<>
   struct print_log_value<fc::variant> {
      void operator()( std::ostream& osm, const fc::variant& v )
      {
         ::operator<<( osm, v );
      }
   };

   template<>
   struct print_log_value<fc::variant_object> {
      void operator()( std::ostream& osm, const fc::variant_object& v )
      {
         ::operator<<( osm, v );
      }
   };

   template<>
   struct print_log_value<fc::variant_object::entry> {
      void operator()( std::ostream& osm, const fc::variant_object::entry& e )
      {
         ::operator<<( osm, e );
      }
   };

} } }

// list common system names here to avoid "magic values" in tests
namespace eosio { namespace chain { namespace config {

static const auto names_account_name   = N(cyber.names);
static const auto ram_account_name     = N(cyber.ram);
static const auto ramfee_account_name  = N(cyber.ramfee);
static const auto bpay_account_name    = N(cyber.bpay);
static const auto vpay_account_name    = N(cyber.vpay);
static const auto saving_account_name  = N(cyber.saving);

static const std::set<account_name> native_accounts = {
    system_account_name, msig_account_name, domain_account_name, govern_account_name, stake_account_name
};

}}};

namespace eosio { namespace testing {
   std::vector<uint8_t> read_wasm( const char* fn );
   std::vector<char>    read_abi( const char* fn );
   std::string          read_wast( const char* fn );
   using namespace eosio::chain;

   fc::variant_object filter_fields(const fc::variant_object& filter, const fc::variant_object& value);

   bool expect_assert_message(const fc::exception& ex, string expected);

   /**
    *  @class tester
    *  @brief provides utility function to simplify the creation of unit tests
    */
   class base_tester {
      public:
         typedef string action_result;

         static const uint32_t DEFAULT_EXPIRATION_DELTA = 6;

         static const uint32_t DEFAULT_BILLED_CPU_TIME_US = 2000;
         static const uint64_t DEFAULT_BILLED_RAM_BYTES = 1024;
         static const fc::microseconds abi_serializer_max_time;

         virtual ~base_tester() {};

         static controller::config default_config(string chaindb_sys_name = string());

         void init(controller::config config, bool push_genesis = true, db_read_mode read_mode = db_read_mode::SPECULATIVE);
         void init(controller::config config, snapshot_reader_ptr snapshot = nullptr);

         void close();
         void open( snapshot_reader_ptr snapshot );
         bool is_same_chain( base_tester& other );

         virtual signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() ) = 0;
         virtual signed_block_ptr produce_empty_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() ) = 0;
         virtual signed_block_ptr finish_block() = 0;
         signed_block_ptr     wait_irreversible_block( uint32_t, bool empty_blocks = false, const std::set<account_name>& disabled_producers = std::set<account_name>() );
         signed_block_ptr     produce_blocks( uint32_t n = 1, bool empty = false, const std::set<account_name>& disabled_producers = std::set<account_name>() );
         void                 produce_blocks_until_end_of_round(const std::set<account_name>& disabled_producers = std::set<account_name>());
         void                 produce_blocks_for_n_rounds(const uint32_t num_of_rounds = 1, const std::set<account_name>& disabled_producers = std::set<account_name>());
         // Produce minimal number of blocks as possible to spend the given time without having any producer become inactive
         void                 produce_min_num_of_blocks_to_spend_time_wo_inactive_prod(const fc::microseconds target_elapsed_time = fc::microseconds(), const std::set<account_name>& disabled_producers = std::set<account_name>());
         signed_block_ptr     push_block(signed_block_ptr b);

         /**
          * These transaction IDs represent transactions available in the head chain state as scheduled
          * or otherwise generated transactions.
          *
          * calling push_scheduled_transaction with these IDs will remove the associated transaction from
          * the chain state IFF it succeeds or objectively fails
          *
          * @return
          */
         vector<transaction_id_type> get_scheduled_transactions() const;

         transaction_trace_ptr    push_transaction( packed_transaction& trx, fc::time_point deadline = fc::time_point::maximum(),
                                                    uint32_t billed_cpu_time_us = DEFAULT_BILLED_CPU_TIME_US, uint64_t billed_ram_bytes = DEFAULT_BILLED_RAM_BYTES );
         transaction_trace_ptr    push_transaction( signed_transaction& trx, fc::time_point deadline = fc::time_point::maximum(),
                                                    uint32_t billed_cpu_time_us = DEFAULT_BILLED_CPU_TIME_US, uint64_t billed_ram_bytes = DEFAULT_BILLED_RAM_BYTES,
                                                    bool add_nested = false );
         transaction_trace_ptr    push_transaction2(signed_transaction& trx, bool add_nested = false);
         action_result            push_action(action&& cert_act, uint64_t authorizer); // TODO/QUESTION: Is this needed?

         transaction_trace_ptr    push_action( const account_name& code,
                                               const action_name& acttype,
                                               const account_name& actor,
                                               const variant_object& data,
                                               uint32_t expiration = DEFAULT_EXPIRATION_DELTA,
                                               uint32_t delay_sec = 0 );
         transaction_trace_ptr    push_action( const account_name& code,
                                               const action_name& acttype,
                                               const vector<account_name>& actors,
                                               const variant_object& data,
                                               uint32_t expiration = DEFAULT_EXPIRATION_DELTA,
                                               uint32_t delay_sec = 0 );
         transaction_trace_ptr    push_action( const account_name& code,
                                               const action_name& acttype,
                                               const vector<permission_level>& auths,
                                               const variant_object& data,
                                               uint32_t expiration = DEFAULT_EXPIRATION_DELTA,
                                               uint32_t delay_sec = 0,
                                               bool add_nested = false );

         action get_action( account_name code, action_name acttype, vector<permission_level> auths,
                                         const variant_object& data )const;

         void  set_transaction_headers( transaction& trx,
                                        uint32_t expiration = DEFAULT_EXPIRATION_DELTA,
                                        uint32_t delay_sec = 0 )const;

         vector<transaction_trace_ptr>  create_accounts( vector<account_name> names,
                                                         bool multisig = false,
                                                         bool include_code = true
                                                       )
         {
            vector<transaction_trace_ptr> traces;
            traces.reserve(names.size());
            for( auto n : names ) traces.emplace_back( create_account( n, config::system_account_name, multisig, include_code ) );
            return traces;
         }

         void                  push_genesis_block();
         vector<producer_key>  get_producer_keys( const vector<account_name>& producer_names )const;
         transaction_trace_ptr set_producers(const vector<account_name>& producer_names);

         void link_authority( account_name account, account_name code,  permission_name req, action_name type = "" );
         void unlink_authority( account_name account, account_name code, action_name type = "" );
         void set_authority( account_name account, permission_name perm, authority auth,
                                     permission_name parent, const vector<permission_level>& auths, const vector<private_key_type>& keys );
         void set_authority( account_name account, permission_name perm, authority auth,
                                     permission_name parent = config::owner_name );
         void delete_authority( account_name account, permission_name perm,  const vector<permission_level>& auths, const vector<private_key_type>& keys );
         void delete_authority( account_name account, permission_name perm );

         transaction_trace_ptr create_account( account_name name,
                                               account_name creator = config::system_account_name,
                                               bool multisig = false,
                                               bool include_code = true
                                             );

         transaction_trace_ptr push_reqauth( account_name from, const vector<permission_level>& auths, const vector<private_key_type>& keys );
         transaction_trace_ptr push_reqauth(account_name from, string role, bool multi_sig = false);
         // use when just want any old non-context free action
         transaction_trace_ptr push_dummy(account_name from, const string& v = "blah", uint32_t billed_cpu_time_us = DEFAULT_BILLED_CPU_TIME_US );
         transaction_trace_ptr transfer( account_name from, account_name to, asset amount, string memo, account_name currency );
         transaction_trace_ptr transfer( account_name from, account_name to, string amount, string memo, account_name currency );
         transaction_trace_ptr issue( account_name to, string amount, account_name currency , string memo);

         template<typename ObjectType>
         const auto& get(const cyberway::chaindb::oid< ObjectType >& key) {
            return control->chaindb().get<ObjectType>(key);
         }

         template<typename ObjectType, typename IndexBy, typename... Args>
         const auto& get( Args&&... args ) {
            return control->chaindb().get<ObjectType,IndexBy>( forward<Args>(args)... );
         }

         template<typename ObjectType, typename IndexBy, typename... Args>
         const auto* find( Args&&... args ) {
            return control->chaindb().find<ObjectType,IndexBy>( forward<Args>(args)... );
         }

         template< typename KeyType = fc::ecc::private_key_shim >
         static private_key_type get_private_key( name keyname, string role = "owner" ) {
            return private_key_type::regenerate<KeyType>(
                fc::sha256::hash(string(
                    config::native_accounts.find(keyname) != config::native_accounts.end() ?
                        name(config::system_account_name) :
                        keyname
                    )+role));
         }

         template< typename KeyType = fc::ecc::private_key_shim >
         static public_key_type get_public_key( name keyname, string role = "owner" ) {
            return get_private_key<KeyType>( keyname, role ).get_public_key();
         }

         void              set_code( account_name name, const char* wast, const private_key_type* signer = nullptr );
         void              set_code( account_name name, const vector<uint8_t> wasm, const private_key_type* signer = nullptr  );
         void              set_abi( account_name name, const char* abi_json, const private_key_type* signer = nullptr );

         bool                          chain_has_transaction( const transaction_id_type& txid ) const;
         const transaction_receipt&    get_transaction_receipt( const transaction_id_type& txid ) const;

         asset                         get_currency_balance( const account_name& contract,
                                                             const symbol&       asset_symbol,
                                                             const account_name& account ) const;

         vector<char> get_row_by_account( uint64_t code, uint64_t scope, uint64_t table, const account_name& act ) const;

         map<account_name, block_id_type> get_last_produced_block_map()const { return last_produced_block; };
         void set_last_produced_block_map( const map<account_name, block_id_type>& lpb ) { last_produced_block = lpb; }

         static vector<uint8_t> to_uint8_vector(const string& s);

         static vector<uint8_t> to_uint8_vector(uint64_t x);

         static uint64_t to_uint64(fc::variant x);

         static string to_string(fc::variant x);

         static action_result success() { return string(); }

         static action_result error( const string& msg ) { return msg; }

         static action_result wasm_assert_msg( const string& msg ) { return "assertion failure with message: " + msg; }

         static action_result wasm_assert_code( uint64_t error_code ) { return "assertion failure with error code: " + std::to_string(error_code); }

         auto get_resolver() {
            return [this]( const account_name& name ) -> optional<abi_serializer> {
               try {
                  const auto& accnt = control->chaindb().get<account_object>( name );
                  abi_def abi;
                  if( abi_serializer::to_abi( accnt.abi, abi )) {
                     return abi_serializer( abi, abi_serializer_max_time );
                  }
                  return optional<abi_serializer>();
               } FC_RETHROW_EXCEPTIONS( error, "Failed to find or parse ABI for ${name}", ("name", name))
            };
         }

         void sync_with(base_tester& other);

         const controller::config& get_config() const {
            return cfg;
         }

      protected:
         signed_block_ptr _produce_block( fc::microseconds skip_time, bool skip_pending_trxs = false, uint32_t skip_flag = 0, const std::set<account_name>& disabled_producers = std::set<account_name>() );
         void             _start_block(fc::time_point block_time);
         signed_block_ptr _finish_block();

      // Fields:
      protected:
         // tempdir field must come before control so that during destruction the tempdir is deleted only after controller finishes
         fc::temp_directory                            tempdir;
      public:
         unique_ptr<controller> control;
         std::map<chain::public_key_type, chain::private_key_type> block_signing_private_keys;
         bool ignore_scheduled_fail = false; // to test deferred more flexible
      protected:
         controller::config                            cfg;
         map<transaction_id_type, transaction_receipt> chain_transactions;
         map<account_name, block_id_type>              last_produced_block;
   };

   class tester : public base_tester {
   public:
      tester(controller::config config = default_config(), bool push_genesis = true, db_read_mode read_mode = db_read_mode::SPECULATIVE) {
         init(config, push_genesis, read_mode);
      }

      signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() )override {
         return _produce_block(skip_time, false, skip_flag, disabled_producers);
      }

      signed_block_ptr produce_empty_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() )override {
         control->abort_block();
         return _produce_block(skip_time, true, skip_flag, disabled_producers);
      }

      signed_block_ptr finish_block()override {
         return _finish_block();
      }

      bool validate() { return true; }
   };

   class validating_tester : public base_tester {
   public:
      virtual ~validating_tester() {
         try {
            if( num_blocks_to_producer_before_shutdown > 0 )
               produce_blocks( num_blocks_to_producer_before_shutdown );
            if (!skip_validate)
               BOOST_REQUIRE_EQUAL( validate(), true );
         } catch( const fc::exception& e ) {
            wdump((e.to_detail_string()));
         }
      }
      controller::config vcfg;

      validating_tester(const flat_set<account_name>& trusted_producers = flat_set<account_name>()) {
         vcfg = default_config("_VALIDATE_");
         vcfg.trusted_producers = trusted_producers;

         validating_node = std::make_unique<controller>(vcfg);
         validating_node->add_indices();
         validating_node->startup( []() { return false; } );

         init(default_config(), true);
      }

      signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0 /*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() )override {
         auto sb = _produce_block(skip_time, false, skip_flag | 2, disabled_producers);
         auto bs = validating_node->create_block_state_future( sb );
         validating_node->push_block( bs );

         return sb;
      }

      signed_block_ptr produce_block_no_validation( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0 /*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() ) {
         return _produce_block(skip_time, false, skip_flag | 2, disabled_producers);
      }

      void validate_push_block(const signed_block_ptr& sb) {
         auto bs = validating_node->create_block_state_future( sb );
         validating_node->push_block( bs );
      }

      signed_block_ptr produce_empty_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0 /*skip_missed_block_penalty*/, const std::set<account_name>& disabled_producers = std::set<account_name>() )override {
         control->abort_block();
         auto sb = _produce_block(skip_time, true, skip_flag | 2, disabled_producers);
         auto bs = validating_node->create_block_state_future( sb );
         validating_node->push_block( bs );

         return sb;
      }

      signed_block_ptr finish_block()override {
         return _finish_block();
      }

      bool validate() {

        auto hbh = control->head_block_state()->header;
        auto vn_hbh = validating_node->head_block_state()->header;
        bool ok = control->head_block_id() == validating_node->head_block_id() &&
               hbh.previous == vn_hbh.previous &&
               hbh.timestamp == vn_hbh.timestamp &&
               hbh.transaction_mroot == vn_hbh.transaction_mroot &&
               hbh.action_mroot == vn_hbh.action_mroot &&
               hbh.producer == vn_hbh.producer;

        validating_node.reset();
        validating_node = std::make_unique<controller>(vcfg);
        validating_node->add_indices();
        validating_node->startup( []() { return false; } );

        return ok;
      }

      unique_ptr<controller>   validating_node;
      uint32_t                 num_blocks_to_producer_before_shutdown = 0;
      bool                     skip_validate = false;
   };

   /**
    * Utility predicate to check whether an fc::exception message is equivalent to a given string
    */
   struct fc_exception_message_is {
      fc_exception_message_is( const string& msg )
            : expected( msg ) {}

      bool operator()( const fc::exception& ex );

      string expected;
   };

  /**
   * Utility predicate to check whether an fc::exception message starts with a given string
   */
  struct fc_exception_message_starts_with {
     fc_exception_message_starts_with( const string& msg )
           : expected( msg ) {}

     bool operator()( const fc::exception& ex );

     string expected;
  };

  /**
   * Utility predicate to check whether an fc::assert_exception message is equivalent to a given string
   */
  struct fc_assert_exception_message_is {
     fc_assert_exception_message_is( const string& msg )
           : expected( msg ) {}

     bool operator()( const fc::assert_exception& ex );

     string expected;
  };

  /**
   * Utility predicate to check whether an fc::assert_exception message starts with a given string
   */
  struct fc_assert_exception_message_starts_with {
     fc_assert_exception_message_starts_with( const string& msg )
           : expected( msg ) {}

     bool operator()( const fc::assert_exception& ex );

     string expected;
  };

  /**
   * Utility predicate to check whether an eosio_assert message is equivalent to a given string
   */
  struct eosio_assert_message_is {
     eosio_assert_message_is( const string& msg )
           : expected( "assertion failure with message: " ) {
        expected.append( msg );
     }

     bool operator()( const eosio_assert_message_exception& ex );

     string expected;
  };

  /**
   * Utility predicate to check whether an eosio_assert message starts with a given string
   */
  struct eosio_assert_message_starts_with {
     eosio_assert_message_starts_with( const string& msg )
           : expected( "assertion failure with message: " ) {
        expected.append( msg );
     }

     bool operator()( const eosio_assert_message_exception& ex );

     string expected;
  };

  /**
   * Utility predicate to check whether an eosio_assert_code error code is equivalent to a given number
   */
  struct eosio_assert_code_is {
     eosio_assert_code_is( uint64_t error_code )
           : expected( "assertion failure with error code: " ) {
        expected.append( std::to_string(error_code) );
     }

     bool operator()( const eosio_assert_code_exception& ex );

     string expected;
  };

} } /// eosio::testing

max_stars_repo_name: GolosChain/eos

max_issues_repo_name: GolosChain/eos

max_forks_repo_name: GolosChain/eos


text:
//! [dot-main]
#include <boost/simd/function/load.hpp>
#include <boost/simd/function/sum.hpp>
#include <boost/simd/pack.hpp>

template <typename Value>
Value scaldot(Value* first1, Value* last1, Value* first2)
{
  Value v(0);

  for (; first1 < last1; ++first1, ++first2) {
    v += (*first1) * (*first2);
  }
  return v;
}

template <typename Value>
Value simddot(Value* first1, Value* last1, Value* first2)
{
  namespace bs = boost::simd;
  using pack_t = bs::pack<Value>;

  pack_t tmp{0};
  int card = pack_t::static_size;

  for (; first1 + card <= last1; first1 += card, first2 += card) {
    // Load current values from the datasets
    pack_t x1 = bs::load<pack_t>(first1);
    pack_t x2 = bs::load<pack_t>(first2);
    // Computation
    tmp = tmp + x1 * x2;
  }

  Value dot_product = bs::sum(tmp);
  for (; first1 < last1; ++first1, ++first2) {
    dot_product += (*first1) * (*first2);
  }

  return dot_product;
}

int main()
{
  namespace bs = boost::simd;
  using pack_t = bs::pack<float>;

  const size_t size = 113;
  float card_float  = bs::cardinal_of<pack_t>();

  std::vector<float> v1(size), v2(size);
  std::iota(v1.begin(), v1.end(), 0);
  std::iota(v2.begin(), v2.end(), 1);
  std::cout << "scalar dot product output " << scaldot(v1.data(), v1.data() + size, v2.data())
            << std::endl;
  std::cout << "simd   dot product output " << simddot(v1.data(), v1.data() + size, v2.data())
            << std::endl;
};
// This code can be compiled using (for instance for gcc)
// g++ dotmain.cpp -msse4.2 -std=c++11 -O3 -DNDEBUG -o dotmain
// -I/path_to/boost_simd/ -I/path_to/boost/
//! [dot-main]


text:
/*
 * Copyright 2015 David A. Boyuka II
 *
 * 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.
 */

/*
 * wah.hpp
 *
 *  Created on: Jul 10, 2014
 *      Author: David A. Boyuka II
 */
#ifndef WAH_HPP_
#define WAH_HPP_

#include <iterator>
#include <cstdint>
#include <boost/smart_ptr.hpp>
#include <boost/limits.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/binary_object.hpp>

// FastBit library
#include <bitvector.h>

#include "pique/region/region-encoding.hpp"

#include "pique/util/fixed-archive.hpp"

// WAHRegionEncoding, a concrete subclass of RegionEncoding utilizing a WAH-compressed bitmap encoding
class WAHRegionEncoding : public RegionEncoding {
public:
	static constexpr RegionEncoding::Type TYPE = RegionEncoding::Type::WAH;

public:
	WAHRegionEncoding() : bits() {}
	WAHRegionEncoding(uint64_t domain_size) : bits() {
		assert(domain_size <= std::numeric_limits< ibis::bitvector::word_t >::max());
		bits.appendFill(0, domain_size);
	}
	WAHRegionEncoding(uint64_t nelem, bool filled) : bits() {
		assert(nelem <= std::numeric_limits< ibis::bitvector::word_t >::max());
		bits.appendFill(filled ? 1 : 0, (ibis::bitvector::word_t)nelem);
	}
	virtual ~WAHRegionEncoding() {}

	virtual RegionEncoding::Type get_type() const { return RegionEncoding::Type::WAH; }

    virtual size_t get_size_in_bytes() const { return bits.getSerialSize(); }
    virtual void dump() const;

    virtual uint64_t get_domain_size() const { return bits.size(); }
	virtual uint64_t get_element_count() const;
	virtual void convert_to_rids(std::vector<uint32_t> &out, bool sorted = false, bool preserve_self = true);
	virtual void convert_to_rids(std::vector<uint64_t> &out, uint64_t offset, bool sorted = false, bool preserve_self = true);

	virtual void save_to_stream(std::ostream &out) { boost::archive::simple_binary_oarchive(out, boost::archive::no_header) << *this; }
	virtual void load_from_stream(std::istream &in) { boost::archive::simple_binary_iarchive(in, boost::archive::no_header) >> *this; }

	virtual bool operator==(const RegionEncoding &other) const;

private:
	template<typename rid_t, bool has_offset>
	void convert_to_rids(std::vector< rid_t > &out, uint64_t offset);

    friend class boost::serialization::access;
    template<typename Archive> void serialize(Archive &ar, const unsigned int version) {
    	using word_t = ibis::bitvector::word_t;

    	if (Archive::is_loading::value)
    		bits = ibis::bitvector();

    	ar & bits.nbits;
    	ar & bits.nset;
    	ar & bits.active.nbits;
    	ar & bits.active.val;

		size_t n;
		if (Archive::is_saving::value)
			n = bits.m_vec.size();
		ar & n;
		if (Archive::is_loading::value)
    		bits.m_vec = ibis::array_t< word_t >(n);

		ar & boost::serialization::make_binary_object(
				(void*)bits.m_vec.begin(),
				n * sizeof(word_t));
    }

private:
    ibis::bitvector bits;

    friend class WAHRegionEncoder;
    friend class WAHSetOperations;
    friend class WAHToBitmapConverter;
};

template<> class RegionEncoding::TypeToClass<RegionEncoding::Type::WAH> { typedef WAHRegionEncoding REClass; };

BOOST_CLASS_IMPLEMENTATION(WAHRegionEncoding, boost::serialization::object_serializable) // no version information serialized

#endif /* WAH_HPP_ */

max_stars_repo_name: daboyuka/PIQUE

max_issues_repo_name: daboyuka/PIQUE

max_forks_repo_name: daboyuka/PIQUE