text:
//
// Copyright © 2019 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include "inference_test_image.hpp"

#include <armnn/Tensor.hpp>
#include <armnn/TypesUtils.hpp>

#include <boost/format.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/program_options.hpp>

#include <string>
#include <vector>
#include <istream>

namespace armnn
{

inline std::istream& operator>>(std::istream& in, armnn::Compute& compute)
{
    std::string token;
    in >> token;
    compute = armnn::ParseComputeDevice(token.c_str());
    if (compute == armnn::Compute::Undefined)
    {
        in.setstate(std::ios_base::failbit);
        throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
    }
    return in;
}

inline std::istream& operator>>(std::istream& in, armnn::BackendId& backend)
{
    std::string token;
    in >> token;
    armnn::Compute compute = armnn::ParseComputeDevice(token.c_str());
    if (compute == armnn::Compute::Undefined)
    {
        in.setstate(std::ios_base::failbit);
        throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
    }
    backend = compute;
    return in;
}

} // namespace armnn

// Prepare a qasymm8 image tensor
std::vector<uint8_t> PrepareImageTensor(const std::string& imagePath,
                                        unsigned int newWidth,
                                        unsigned int newHeight,
                                        const NormalizationParameters& normParams);

template<typename TContainer>
armnn::InputTensors MakeInputTensors(const std::vector<armnn::BindingPointInfo>& inputBindings,
                                     const std::vector<TContainer>& inputDataContainers)
{
    armnn::InputTensors inputTensors;

    const size_t numInputs = inputBindings.size();
    if (numInputs != inputDataContainers.size())
    {
        throw armnn::Exception(boost::str(boost::format("The number of inputs does not match the number of "
                                                        "tensor data containers: %1% != %2%")
                                          % numInputs
                                          % inputDataContainers.size()));
    }

    for (size_t i = 0; i < numInputs; i++)
    {
        const armnn::BindingPointInfo& inputBinding = inputBindings[i];
        const TContainer& inputData = inputDataContainers[i];

        boost::apply_visitor([&](auto&& value)
        {
            if (value.size() != inputBinding.second.GetNumElements())
            {
               throw armnn::Exception(boost::str(boost::format("The input tensor has incorrect size "
                                                               "(expected %1% got %2%)")
                                                 % inputBinding.second.GetNumElements()
                                                 % value.size()));
            }

            armnn::ConstTensor inputTensor(inputBinding.second, value.data());
            inputTensors.push_back(std::make_pair(inputBinding.first, inputTensor));
        },
        inputData);
    }

    return inputTensors;
}

template<typename TContainer>
armnn::OutputTensors MakeOutputTensors(const std::vector<armnn::BindingPointInfo>& outputBindings,
                                       std::vector<TContainer>& outputDataContainers)
{
    armnn::OutputTensors outputTensors;

    const size_t numOutputs = outputBindings.size();
    if (numOutputs != outputDataContainers.size())
    {
        throw armnn::Exception(boost::str(boost::format("Number of outputs does not match number of "
                                                        "tensor data containers: %1% != %2%")
                                          % numOutputs
                                          % outputDataContainers.size()));
    }

    for (size_t i = 0; i < numOutputs; i++)
    {
        const armnn::BindingPointInfo& outputBinding = outputBindings[i];
        TContainer& outputData = outputDataContainers[i];

        boost::apply_visitor([&](auto&& value)
        {
            if (value.size() != outputBinding.second.GetNumElements())
            {
                throw armnn::Exception("Output tensor has incorrect size");
            }

            armnn::Tensor outputTensor(outputBinding.second, value.data());
            outputTensors.push_back(std::make_pair(outputBinding.first, outputTensor));
        },
        outputData);
    }

    return outputTensors;
}

max_stars_repo_name: felix-johnny/ML-examples

max_issues_repo_name: phecda-xu/ML-examples

max_forks_repo_name: phecda-xu/ML-examples


text:
// -----------------------------------------------------------------------
// pion-common: a collection of common libraries used by the Pion Platform
// -----------------------------------------------------------------------
// Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//

#ifndef __PION_PIONPOOLALLOCATOR_HEADER__
#define __PION_PIONPOOLALLOCATOR_HEADER__

#include <cstdlib>
#include <boost/array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/pool/pool.hpp>
#include <pion/PionConfig.hpp>
#include <pion/PionException.hpp>

#if defined(PION_HAVE_MALLOC_TRIM)
	#include <malloc.h>
#endif

/// the following enables use of the lock-free cache
#if defined(PION_HAVE_LOCKFREE)
#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning)
#endif
	#include <boost/lockfree/detail/tagged_ptr.hpp>
#ifdef _MSC_VER
	#pragma warning(pop)
#endif
	#include <boost/lockfree/atomic_int.hpp>
#endif

namespace pion {	// begin namespace pion

///
/// PionPoolAllocator: a thread-safe, small object allocator that sacrifices
///                    memory utilization for performance.  It combines a
///                    collection of fixed-size pooled memory allocators with
///                    lock-free caches to achieve nearly wait-free, constant
///                    time performance when used for an extended period of time
///
template <std::size_t MinSize = 16, std::size_t MaxSize = 256>
class PionPoolAllocator
	: private boost::noncopyable
{
public:

	/// virtual destructor
	virtual ~PionPoolAllocator()
	{}

	/// default constructor
	PionPoolAllocator(void)
	{
		for (std::size_t n = 0; n < NumberOfAllocs; ++n) {
			m_pools[n].reset(new FixedSizeAlloc((n+1) * MinSize));
		}
	}

	/**
	 * allocates a block of memory
	 *
	 * @param n minimum size of the new memory block, in bytes
	 *
	 * @return void * raw pointer to the new memory block
	 */
	inline void *malloc(std::size_t n)
	{
		// check for size greater than MaxSize
		if (n > MaxSize)
			return ::malloc(n);
		FixedSizeAlloc *pool_ptr = getPool(n);

#if defined(PION_HAVE_LOCKFREE)
		while (true) {
			// get copy of free list pointer
			FreeListPtr old_free_ptr(pool_ptr->m_free_ptr);
			if (! old_free_ptr)
				break;	// use pool alloc if free list is empty

			// use CAS operation to swap the free list pointer
			if (pool_ptr->m_free_ptr.cas(old_free_ptr, old_free_ptr->next.get_ptr()))
				return reinterpret_cast<void*>(old_free_ptr.get_ptr());
		}
#endif

		boost::unique_lock<boost::mutex> pool_lock(pool_ptr->m_mutex);
		return pool_ptr->m_pool.malloc();
	}

	/**
	 * deallocates a block of memory
	 *
	 * @param ptr raw pointer to the block of memory
	 * @param n requested size of the memory block, in bytes (actual size may be larger)
	 */
	inline void free(void *ptr, std::size_t n)
	{
		// check for size greater than MaxSize
		if (n > MaxSize) {
			::free(ptr);
			return;
		}
		FixedSizeAlloc *pool_ptr = getPool(n);
#if defined(PION_HAVE_LOCKFREE)
		while (true) {
			// get copy of free list pointer
			FreeListPtr old_free_ptr(pool_ptr->m_free_ptr);

			// cast memory being released to a free list node
			// and point its next pointer to the current free list
			FreeListNode *node_ptr = reinterpret_cast<FreeListNode*>(ptr);
			node_ptr->next.set_ptr(old_free_ptr.get_ptr());

			// use CAS operation to swap the free list pointer
			if (pool_ptr->m_free_ptr.cas(old_free_ptr, node_ptr))
				break;
		}
#else
		boost::unique_lock<boost::mutex> pool_lock(pool_ptr->m_mutex);
		return pool_ptr->m_pool.free(ptr);
#endif
	}

	/**
	 * releases every memory block that does not have any allocated chunks
	 *
	 * @param pad padding bytes passed to malloc_trim(), if it's supported (default=10MB)
	 *
	 * @return bool true if at least one block of memory was released
	 */
	inline bool release_memory(size_t pad = 10240000UL)
	{
		bool result = false;
/*
		for (std::size_t n = 0; n < NumberOfAllocs; ++n) {
			FixedSizeAlloc *pool_ptr = m_pools[n].get();
			// need to lock before releasing free list because of calls
			// to pool::free()
			boost::unique_lock<boost::mutex> pool_lock(pool_ptr->m_mutex);
#if defined(PION_HAVE_LOCKFREE)
			while (true) {
				// get copy of free list pointer
				FreeListPtr old_free_ptr(pool_ptr->m_free_ptr);
				if (! old_free_ptr)
					break;	// all done: free list is empty

				// use CAS operation to swap the free list pointer
				if (pool_ptr->m_free_ptr.cas(old_free_ptr, old_free_ptr->next.get_ptr()))
					pool_ptr->m_pool.free(old_free_ptr.get_ptr());	// release memory from pool
			}
#endif
			if (pool_ptr->m_pool.release_memory())
				result = true;
		}
#if defined(PION_HAVE_MALLOC_TRIM)
		::malloc_trim(pad);
#endif
*/
		return result;
	}

protected:

#if defined(PION_HAVE_LOCKFREE)
	/// data structure used to represent a free node
	struct FreeListNode {
		boost::lockfree::tagged_ptr<struct FreeListNode>	next;
	};

	/// data type for a tagged free-list pointer
	typedef boost::lockfree::tagged_ptr<struct FreeListNode>	FreeListPtr;
#else
	typedef void *	FreeListPtr;
#endif

	/// ensure that:
	///   a) MaxSize >= MinSize
	///   b) MaxSize is a multiple of MinSize
	///   c) MinSize >= sizeof(FreeNodePtr)  [usually 16]
	BOOST_STATIC_ASSERT(MaxSize >= MinSize);
	BOOST_STATIC_ASSERT(MaxSize % MinSize == 0);
#if defined(PION_HAVE_LOCKFREE)
	BOOST_STATIC_ASSERT(MinSize >= sizeof(FreeListNode));
#endif

	/// constant representing the number of fixed-size pool allocators
	enum { NumberOfAllocs = ((MaxSize-1) / MinSize) + 1 };

	/**
	 * data structure used to represent a pooled memory
	 * allocator for blocks of a specific size
	 */
	struct FixedSizeAlloc
	{
		/**
		 * constructs a new fixed-size pool allocator
		 *
		 * @param size size of memory blocks managed by this allocator, in bytes
		 */
		FixedSizeAlloc(std::size_t size)
			: m_size(size), m_pool(size), m_free_ptr(NULL)
		{}

		/// used to protect access to the memory pool
		boost::mutex		m_mutex;

		/// size of memory blocks managed by this allocator, in bytes
		std::size_t			m_size;

		/// underlying pool allocator used for memory management
		boost::pool<>		m_pool;

		/// pointer to a list of free nodes (for lock-free cache)
		FreeListPtr			m_free_ptr;
	};

	/**
	 * gets an appropriate fixed-size pool allocator
	 *
	 * @param n the number of bytes to be (de)allocated
	 *
	 * @return FixedSizeAlloc* pointer to the appropriate fixed-size allocator
	 */
	inline FixedSizeAlloc* getPool(const std::size_t n)
	{
		PION_ASSERT(n > 0);
		PION_ASSERT(n <= MaxSize);
		return m_pools[ (n-1) / MinSize ].get();
	}

private:

	/// a collection of fixed-size pool allocators
	boost::array<boost::scoped_ptr<FixedSizeAlloc>, NumberOfAllocs>	m_pools;
};

}	// end namespace pion

#endif

ext: hpp

max_stars_repo_name: marshallmcmullen/pion

max_issues_repo_name: marshallmcmullen/pion

max_forks_repo_name: marshallmcmullen/pion


text:
/**
 * \file libsanm/tensor_linalg.cpp
 * This file is part of SANM, a symbolic asymptotic numerical solver.
 */

#include "libsanm/tensor_impl_helper.h"

#include <Eigen/Dense>

using namespace sanm;

namespace {
/*!
 * \brief compute cofactor of a single matrix
 * \param s_prod_rev a workspace of size dim+1, and the last value must be
 *      initialized to one
 */
template <int mat_dim>
void compute_cofactor(EigenMat<mat_dim, mat_dim>& mdst,
                      EigenMat<mat_dim, mat_dim>& msrc, fp_t* s_prod_rev) {
    Eigen::Index dim = msrc.rows();

    Eigen::JacobiSVD<Eigen::Matrix<fp_t, mat_dim, mat_dim>> svd{
            msrc, Eigen::ComputeFullU | Eigen::ComputeFullV};

    if (svd.rank() + 2 <= dim) {
        mdst.setZero();
        return;
    }

    // det(S) * S.inv()
    Eigen::Matrix<fp_t, mat_dim, 1> sinvd = svd.singularValues();
    if constexpr (mat_dim == 2) {
        fp_t a = sinvd(0), b = sinvd(1);
        sinvd(0) = b;
        sinvd(1) = a;
    } else if constexpr (mat_dim == 3) {
        fp_t a = sinvd(0), b = sinvd(1), c = sinvd(2);
        sinvd(0) = b * c;
        sinvd(1) = a * c;
        sinvd(2) = a * b;
    } else {
        for (int i = dim - 1; i >= 0; --i) {
            s_prod_rev[i] = s_prod_rev[i + 1] * sinvd[i];
        }
        fp_t prod = 1;
        for (Eigen::Index i = 0; i < dim; ++i) {
            fp_t orig = sinvd(i);
            sinvd(i) = prod * s_prod_rev[i + 1];
            prod *= orig;
        }
    }

    fp_t sign = (svd.matrixU() * svd.matrixV().transpose()).determinant();
    if (sign < 0) {
        sinvd = -sinvd;
    }
    mdst = svd.matrixU() * sinvd.asDiagonal() * svd.matrixV().transpose();
}

template <typename T>
constexpr T get_from_pair(int d, T x, T y) {
    return d == 0 ? x : y;
}

CBLAS_TRANSPOSE cblas_trans(bool t) {
    return t ? CblasTrans : CblasNoTrans;
}
}  // anonymous namespace

TensorND& TensorND::as_mm(const TensorND& lhs, const TensorND& rhs, bool accum,
                          bool trans_lhs, bool trans_rhs) {
    SANM_SCOPED_PROFILER("mm");
    sanm_assert(this != &lhs && this != &rhs);
    sanm_assert(lhs.rank() == 2 && rhs.rank() == 2);
    TensorShape dst_shape{
            get_from_pair(trans_lhs, lhs.shape(0), lhs.shape(1)),
            get_from_pair(trans_rhs ^ 1, rhs.shape(0), rhs.shape(1))};

    if (accum) {
        sanm_assert(shape() == dst_shape, "mm accum: expect shape %s, got %s",
                    dst_shape.str().c_str(), shape().str().c_str());

        if (lhs.is_zero() || rhs.is_zero()) {
            return *this;
        }
    } else {
        if (lhs.is_zero() || rhs.is_zero()) {
            // do not use set_shape to avoid unnecessary memory allocation
            m_shape = dst_shape;
            return fill_with_inplace(0);
        }
        set_shape(dst_shape);
    }

    static_assert(std::is_same_v<fp_t, double>, "unhandled fp_t");
    if constexpr (std::is_same_v<fp_t, double>) {
        cblas_dgemm(CblasRowMajor, cblas_trans(trans_lhs),
                    cblas_trans(trans_rhs), dst_shape[0], dst_shape[1],
                    get_from_pair(trans_lhs ^ 1, lhs.shape(0), lhs.shape(1)), 1,
                    lhs.ptr(), lhs.shape(1), rhs.ptr(), rhs.shape(1),
                    accum ? 1 : 0, rwptr(), dst_shape[1]);
    }
    return *this;
}

TensorND& TensorND::as_batched_mm(const TensorND& lhs, const TensorND& rhs,
                                  bool accum, bool trans_lhs, bool trans_rhs) {
    SANM_SCOPED_PROFILER("batched_mm");
    sanm_assert(this != &lhs && this != &rhs);
    sanm_assert(
            lhs.rank() == 3 && rhs.rank() == 3 && lhs.shape(0) == rhs.shape(0),
            "batched mm shape mismatch %s vs %s", lhs.shape().str().c_str(),
            rhs.shape().str().c_str());
    const size_t ls0 = lhs.shape(1), ls1 = lhs.shape(2), rs0 = rhs.shape(1),
                 rs1 = rhs.shape(2), batch = lhs.shape(0);
    sanm_assert(get_from_pair(trans_lhs ^ 1, ls0, ls1) ==
                        get_from_pair(trans_rhs, rs0, rs1),
                "matmul shape mismatch: %s vs %s, trans=%d,%d",
                lhs.shape().str().c_str(), rhs.shape().str().c_str(), trans_lhs,
                trans_rhs);

    TensorShape dst_shape{batch, get_from_pair(trans_lhs, ls0, ls1),
                          get_from_pair(trans_rhs ^ 1, rs0, rs1)};

    if (accum) {
        sanm_assert(shape() == dst_shape,
                    "batched_mm accum: expect shape %s, got %s",
                    dst_shape.str().c_str(), shape().str().c_str());

        if (lhs.is_zero() || rhs.is_zero()) {
            return *this;
        }
    } else {
        if (lhs.is_zero() || rhs.is_zero()) {
            // do not use set_shape to avoid unnecessary memory allocation
            m_shape = dst_shape;
            return fill_with_inplace(0);
        }
        set_shape(dst_shape);
    }

    // As of 2020, MKL batched dgemm is still slow for small matrices ...
    // So we roll out our simple accelerated impl using eigen

    auto pa = const_cast<fp_t*>(lhs.ptr()), pb = const_cast<fp_t*>(rhs.ptr()),
         pc = rwptr();
    auto run_static_shape = [pa, pb, pc, batch, accum, trans_lhs,
                             trans_rhs]<int ls0, int ls1, int rs0, int rs1>() {

    // eigen uses col-major; so we compute on the transformed matrices
#define FOREACH_8(cb)                                                       \
    cb(0, 0, 0) cb(0, 0, 1) cb(0, 1, 0) cb(0, 1, 1) cb(1, 0, 0) cb(1, 0, 1) \
            cb(1, 1, 0) cb(1, 1, 1)
#define ACC0 =
#define ACC1 +=
#define TR0(x) x
#define TR1(x) x.transpose()
#define CB(acc, tra, trb)                                               \
    if constexpr (get_from_pair(tra ^ 1, ls0, ls1) ==                   \
                  get_from_pair(trb, rs0, rs1)) {                       \
        constexpr int cs0 = get_from_pair(tra, ls0, ls1),               \
                      cs1 = get_from_pair(trb ^ 1, rs0, rs1);           \
        if (accum == acc && trans_lhs == tra && trans_rhs == trb) {     \
            for (size_t ib = 0; ib < batch; ++ib) {                     \
                EigenMat<ls1, ls0> ta{pa + ib * (ls0 * ls1), ls1, ls0}; \
                EigenMat<rs1, rs0> tb{pb + ib * (rs0 * rs1), rs1, rs0}; \
                EigenMat<cs1, cs0> tc{pc + ib * (cs0 * cs1), cs1, cs0}; \
                tc.noalias() ACC##acc TR##trb(tb) * TR##tra(ta);        \
            }                                                           \
            return;                                                     \
        }                                                               \
    }
        FOREACH_8(CB)
        sanm_assert(0, "impossible");
#undef CB
#undef TR1
#undef TR0
#undef ACC1
#undef ACC0
#undef FOREACH_8
    };

#define CASE(ls0_, ls1_, rs0_, rs1_)                                    \
    do {                                                                \
        if (ls0_ == ls0 && ls1_ == ls1 && rs0_ == rs0 && rs1_ == rs1) { \
            run_static_shape.operator()<ls0_, ls1_, rs0_, rs1_>();      \
            return *this;                                               \
        }                                                               \
    } while (0)

    CASE(1, 1, 1, 1);
    CASE(2, 2, 2, 2);
    CASE(3, 3, 3, 3);
    CASE(4, 4, 4, 4);

    // special handling of shapes can be added here
#undef CASE

    static_assert(std::is_same_v<fp_t, double>, "unhandled fp_t");
    if constexpr (std::is_same_v<fp_t, double>) {
        cblas_dgemm_batch_strided(
                CblasRowMajor, cblas_trans(trans_lhs), cblas_trans(trans_rhs),
                dst_shape[1], dst_shape[2],
                get_from_pair(trans_lhs ^ 1, ls0, ls1), 1, lhs.ptr(), ls1,
                ls0 * ls1, rhs.ptr(), rs1, rs0 * rs1, accum ? 1 : 0, rwptr(),
                dst_shape[2], dst_shape[1] * dst_shape[2], batch);
    }
    return *this;
}

TensorND& TensorND::as_batched_transpose(const TensorND& src) {
    SANM_SCOPED_PROFILER("batched_transpose");
    sanm_assert(this != &src);
    sanm_assert(src.rank() == 3);
    {
        TensorShape oshp = src.shape();
        std::swap(oshp.dim[1], oshp.dim[2]);
        set_shape(oshp);
    }
    if (src.is_zero()) {
        return fill_with_inplace(0);
    }
    auto work = [this, &src]<int mat_dim0, int mat_dim1>() {
        auto sptr = const_cast<fp_t*>(src.ptr()), dptr = this->woptr();
        const size_t batch = src.shape(0);
        const Eigen::Index dim0 = src.shape(1), dim1 = src.shape(2);
        for (size_t i = 0; i < batch; ++i) {
            EigenMat<mat_dim0, mat_dim1> mdst{dptr + i * dim0 * dim1, dim0,
                                              dim1};
            EigenMat<mat_dim1, mat_dim0> msrc{sptr + i * dim0 * dim1, dim1,
                                              dim0};
            mdst = msrc.transpose();
        }
    };

    auto work_dispatch = [&work, &src]<int mat_dim0>() {
        switch (src.shape(2)) {
#define ON(x)                           \
    case x:                             \
        work.operator()<mat_dim0, x>(); \
        break
            ON(1);
            ON(2);
            ON(3);
            ON(4);
#undef ON
            default:
                work.operator()<mat_dim0, Eigen::Dynamic>();
                break;
        }
    };

    switch (src.shape(1)) {
#define ON(x)                          \
    case x:                            \
        work_dispatch.operator()<x>(); \
        break
        ON(1);
        ON(2);
        ON(3);
        ON(4);
#undef ON
        default:
            work_dispatch.operator()<Eigen::Dynamic>();
            break;
    }
    return *this;
}

TensorND& TensorND::as_transpose(const TensorND& src) {
    sanm_assert(src.rank() == 2);
    size_t m = src.shape(0), n = src.shape(1);
    set_shape({n, m});
    if (src.is_zero()) {
        return fill_with_inplace(0);
    }
    auto ei = [](size_t x) -> Eigen::Index { return x; };
    EigenMatDyn mdst{woptr(), ei(m), ei(n)},
            msrc{const_cast<fp_t*>(src.ptr()), ei(n), ei(m)};
    mdst = msrc.transpose();
    return *this;
}

TensorND& TensorND::as_batched_matinv(const TensorND& src) {
    SANM_SCOPED_PROFILER("batched_matinv");
    sanm_assert(this != &src);
    sanm_assert(src.rank() == 3 && src.shape(1) == src.shape(2));
    sanm_assert(!src.is_zero());
    set_shape(src.shape());
    auto work = [this, &src]<int mat_dim>() {
        ScopedAllowMalloc scoped_allow_malloc;
        auto sptr = const_cast<fp_t*>(src.ptr()), dptr = this->woptr();
        const size_t batch = src.shape(0);
        const Eigen::Index dim = src.shape(1);
        for (size_t i = 0; i < batch; ++i) {
            EigenMat<mat_dim, mat_dim> mdst{dptr + i * dim * dim, dim, dim},
                    msrc{sptr + i * dim * dim, dim, dim};
            mdst = msrc.inverse();
        }
    };
    switch (src.shape(1)) {
#define ON(x)                 \
    case x:                   \
        work.operator()<x>(); \
        break
        ON(1);
        ON(2);
        ON(3);
        ON(4);
#undef ON
        default:
            work.operator()<Eigen::Dynamic>();
            break;
    }
    return *this;
}

TensorND& TensorND::as_batched_determinant(const TensorND& src) {
    SANM_SCOPED_PROFILER("batched_det");
    ScopedAllowMalloc allow_mem_alloc;

    sanm_assert(this != &src);
    sanm_assert(src.rank() == 3 && src.shape(1) == src.shape(2));
    set_shape({src.shape(0), 1});
    if (src.is_zero()) {
        return fill_with_inplace(0);
    }
    auto work = [this, &src]<int mat_dim>() {
        auto sptr = const_cast<fp_t*>(src.ptr()), dptr = this->woptr();
        const size_t batch = src.shape(0);
        const Eigen::Index dim = src.shape(1);
        for (size_t i = 0; i < batch; ++i) {
            EigenMat<mat_dim, mat_dim> msrc{sptr + i * dim * dim, dim, dim};
            dptr[i] = msrc.determinant();
        }
    };
    switch (src.shape(1)) {
#define ON(x)                 \
    case x:                   \
        work.operator()<x>(); \
        break
        ON(1);
        ON(2);
        ON(3);
        ON(4);
#undef ON
        default:
            work.operator()<Eigen::Dynamic>();
            break;
    }
    return *this;
}

TensorND& TensorND::as_batched_cofactor(const TensorND& src) {
    SANM_SCOPED_PROFILER("batched_cofactor");
    ScopedAllowMalloc allow_mem_alloc;

    sanm_assert(this != &src);
    sanm_assert(src.rank() == 3 && src.shape(1) == src.shape(2) &&
                src.shape(1) >= 2);
    set_shape(src.shape());
    if (src.is_zero()) {
        return fill_with_inplace(0);
    }
    auto work = [this, &src]<int mat_dim>() {
        auto sptr = const_cast<fp_t*>(src.ptr()), dptr = this->woptr();
        const size_t batch = src.shape(0);
        const Eigen::Index dim = src.shape(1);
        std::unique_ptr<fp_t[]> s_prod_rev{new fp_t[dim + 1]};
        s_prod_rev[dim] = 1;
        for (size_t i = 0; i < batch; ++i) {
            EigenMat<mat_dim, mat_dim> mdst{dptr + i * dim * dim, dim, dim},
                    msrc{sptr + i * dim * dim, dim, dim};
            compute_cofactor(mdst, msrc, s_prod_rev.get());
        }
    };
    switch (src.shape(1)) {
#define ON(x)                 \
    case x:                   \
        work.operator()<x>(); \
        break
        ON(2);
        ON(3);
        ON(4);
#undef ON
        default:
            work.operator()<Eigen::Dynamic>();
            break;
    }
    return *this;
}

TensorND& TensorND::as_batched_mm_vecitem_left(const TensorND& lhs,
                                               const TensorND& rhs,
                                               bool accum) {
    SANM_SCOPED_PROFILER("batched_mm_vecitem");
    sanm_assert(this != &lhs && this != &rhs);
    sanm_assert(lhs.rank() == 3 && rhs.rank() == 3);
    size_t BATCH = lhs.shape(0), M = lhs.shape(1), P = lhs.shape(2),
           K = rhs.shape(1), N = rhs.shape(2);
    sanm_assert(M % K == 0 && BATCH == rhs.shape(0));
    M /= K;

    TensorShape expect_shape{BATCH, M * N, P};
    if (accum) {
        sanm_assert(m_shape == expect_shape);
    } else {
        set_shape(expect_shape);
    }

    if (lhs.is_zero() || rhs.is_zero()) {
        return fill_with_inplace(0);
    }

    auto ei = [](size_t x) -> Eigen::Index { return x; };

    auto lptr = const_cast<fp_t*>(lhs.ptr()),
         rptr = const_cast<fp_t*>(rhs.ptr()), optr = this->woptr();
    for (size_t b = 0; b < BATCH; ++b) {
        EigenMatDyn mat_rhs{rptr + b * K * N, ei(N), ei(K)};
        for (size_t m = 0; m < M; ++m) {
            EigenMatDyn mat_lhs{lptr + (b * M + m) * K * P, ei(P), ei(K)},
                    mat_dst{optr + (b * M + m) * N * P, ei(P), ei(N)};
            if (accum) {
                mat_dst.noalias() += mat_lhs * mat_rhs.transpose();
            } else {
                mat_dst.noalias() = mat_lhs * mat_rhs.transpose();
            }
        }
    }

    return *this;
}

ext: cpp

max_stars_repo_name: jia-kai/SANM

max_issues_repo_name: jia-kai/SANM

max_forks_repo_name: jia-kai/SANM


text:
#ifndef MITAMA_MAYBE_HPP
#define MITAMA_MAYBE_HPP

#include <mitama/maybe/fwd/maybe_fwd.hpp>
#include <mitama/panic.hpp>
#include <mitama/result/detail/fwd.hpp>
#include <mitama/result/detail/meta.hpp>

#include <boost/format.hpp>
#include <boost/hana/functional/fix.hpp>
#include <boost/hana/functional/overload.hpp>
#include <boost/hana/functional/overload_linearly.hpp>
#include <boost/optional.hpp>
#include <boost/utility/in_place_factory.hpp>

#include <functional>
#include <memory>
#include <optional>
#include <type_traits>
#include <utility>

namespace mitama::mitamagic {
template <class, class=void> struct is_pointer_like: std::false_type {};

template <class PointerLike>
struct is_pointer_like<PointerLike,
    std::void_t<
        decltype(std::declval<PointerLike&>().operator->()),
        decltype(*std::declval<PointerLike&>()),
        decltype(bool(std::declval<PointerLike&>()))>>
    : std::true_type
{};

template <class, class=void>
struct element_type;

template <class T>
struct element_type<T, std::enable_if_t<std::disjunction_v<is_pointer_like<T>, std::is_pointer<T>>>> {
    using type = std::remove_reference_t<decltype(*std::declval<T>())>;
};
}

namespace mitama::mitamagic {

template <class T>
class polymorphic_storage {
  public:
    using pointer_type = T*;
    using pointer_const_type = const T*;
    using reference_type = T&;

    virtual ~polymorphic_storage() = default;
    virtual T& deref() = 0;
    virtual bool is_just() const = 0;
    virtual pointer_type get_pointer() = 0;
    virtual pointer_const_type get_pointer() const  = 0;
};

template <class, class=void>
class maybe_view;

template <class T>
class maybe_view<T,
    std::enable_if_t<
        std::disjunction_v<
            mitamagic::is_pointer_like<std::remove_reference_t<T>>,
            std::is_pointer<std::remove_reference_t<T>>>>>
    : public polymorphic_storage<typename mitamagic::element_type<std::decay_t<T>>::type>
{
    T storage_;
  public:
    using reference_type = typename polymorphic_storage<typename mitamagic::element_type<std::decay_t<T>>::type>::reference_type;
    using pointer_type = typename polymorphic_storage<typename mitamagic::element_type<std::decay_t<T>>::type>::pointer_type;
    using pointer_const_type = typename polymorphic_storage<typename mitamagic::element_type<std::decay_t<T>>::type>::pointer_const_type;

    virtual ~maybe_view() = default;
    maybe_view() = delete;

    template <typename U, std::enable_if_t<std::is_convertible_v<U,T>, bool> = false>
    maybe_view(U&& u) : storage_{std::forward<U>(u)} {}

    template <class... Args>
    maybe_view(std::in_place_t, Args&&... args) : storage_{std::forward<Args>(args)...} {}

    template <class U, class... Args>
    maybe_view(std::in_place_type_t<boost::optional<U>>, Args&&... args) : storage_(boost::in_place(std::forward<Args>(args)...)) {}

    template <class U, class... Args>
    maybe_view(std::in_place_type_t<std::shared_ptr<U>>, Args&&... args) : storage_{std::make_shared<U>(std::forward<Args>(args)...)} {}

    template <class U, class... Args>
    maybe_view(std::in_place_type_t<std::unique_ptr<U>>, Args&&... args) : storage_{std::make_unique<U>(std::forward<Args>(args)...)} {}

    bool is_just() const override final {
        return bool(storage_);
    }
    reference_type deref() override final {
        return *storage_;
    }
    pointer_type get_pointer() override final {
        if constexpr (std::is_pointer_v<std::remove_reference_t<T>>) {
            return storage_;
        }
        else {
            return storage_.operator->();
        }
    }
    pointer_const_type get_pointer() const override final {
        if constexpr (std::is_pointer_v<std::remove_reference_t<T>>) {
            return storage_;
        }
        else {
            return storage_.operator->();
        }
    }
};

template <class T> maybe_view(T&&) -> maybe_view<T>;
template <class T, class... Args> maybe_view(std::in_place_type_t<T>, Args&&...) -> maybe_view<T>;

template <class T, class... Args>
inline auto default_maybe_view(Args&&... args) {
    return std::make_shared<maybe_view<boost::optional<T>>>(std::in_place_type<boost::optional<T>>, std::forward<Args>(args)...);
}

}

namespace mitama {

template <class>
struct is_maybe: std::false_type {};

template <class T>
struct is_maybe<maybe<T>>: std::true_type {};

template <class, class>
struct is_maybe_with: std::false_type {};

template <class T>
struct is_maybe_with<maybe<T>, T>: std::true_type {};

class nothing_t {};

template <class T=void>
inline maybe<T> nothing{};

template <>
inline constexpr auto nothing<void> = nothing_t{};

namespace mitamagic {
template <class T, class=void>
struct just_factory {
    template <class... Args>
    static auto invoke(Args&&... args) {
        return maybe<std::remove_reference_t<T>>(std::in_place, std::forward<Args>(args)...);
    }
};

template <class T>
struct just_factory<T,
    std::enable_if_t<
        std::disjunction_v<
            mitamagic::is_pointer_like<std::remove_reference_t<T>>,
            std::is_pointer<std::remove_reference_t<T>>>>>
{
    template <class U>
    static auto invoke(U&& u) {
        return maybe(maybe(std::forward<U>(u)));
    }
};

template <class T>
struct just_factory<std::in_place_type_t<T>>
{
    template <class... Args>
    static auto invoke(Args&&... args) {
        return maybe<T>(std::in_place, std::forward<Args>(args)...);
    }
};
}

class in_place_factory_base {};

template <class... Args>
class in_place_factory: in_place_factory_base {
    std::tuple<Args...> pack;
public:
    constexpr explicit in_place_factory(Args... args): pack(std::forward<Args>(args)...) {}

    template <class T>
    decltype(auto) apply(std::in_place_type_t<T>) const {
        return std::apply([](auto&&... args){ return T(std::forward<decltype(args)>(args)...); }, pack);
    }

    template <class T>
    void* apply(std::in_place_type_t<T>, void* address) const {
        return std::apply([address](auto&&... args) -> void* { return new(address) T(std::forward<decltype(args)>(args)...); }, pack);
    }

    template <class F>
    decltype(auto) apply(F&& supplier) const {
        return std::apply(std::forward<F>(supplier), pack);
    }
};

template <class... Args>
constexpr auto in_place(Args&&... args) {
    return ::mitama::in_place_factory<Args&&...>{std::forward<Args>(args)...};
}

template <class Target=void, class... Ini>
inline auto just(Ini&&... ini) {
    if constexpr (!std::is_void_v<Target>) {
        return mitamagic::just_factory<std::in_place_type_t<Target>>::invoke(std::forward<Ini>(ini)...);
    }
    else if constexpr (sizeof...(Ini) == 1 && std::is_base_of_v<::mitama::in_place_factory_base, std::decay_t<std::tuple_element_t<0, std::tuple<Ini...>>>>) {
        return [](auto&& factory, auto&&...){
            return std::forward<decltype(factory)>(factory);
        }(std::forward<Ini>(ini)...);
    }
    else if constexpr (sizeof...(Ini) == 1) {
        return mitamagic::just_factory<std::tuple_element_t<0, std::tuple<Ini...>>>::invoke(std::forward<Ini>(ini)...);
    }
    else {
        static_assert([]{ return false; }(),
            "Error: Given variadic initializers without Target. Please try `just<Target>(args...)`.");
    }
}

template <class> class maybe_transpose_injector {
public:
    void transpose() = delete;
};

template <mutability _, class T, class E>
class maybe_transpose_injector<maybe<basic_result<_, T, E>>>
{
public:
    basic_result<_, maybe<std::remove_reference_t<T>>, E>
    transpose() const& {
        return
            static_cast<maybe<basic_result<_, T, E>>const*>(this)->is_nothing()
                ? basic_result<_, maybe<std::remove_reference_t<T>>, E>{success{maybe<std::remove_reference_t<T>>{}}}
                : static_cast<maybe<basic_result<_, T, E>>const*>(this)->unwrap().is_ok()
                    ? basic_result<_, maybe<std::remove_reference_t<T>>, E>{success{just(static_cast<maybe<basic_result<_, T, E>>const*>(this)->unwrap().unwrap())}}
                    : basic_result<_, maybe<std::remove_reference_t<T>>, E>{failure{static_cast<maybe<basic_result<_, T, E>>const*>(this)->unwrap().unwrap_err()}};
    }
};

template <class T, class=void>
class maybe_unwrap_or_default_injector {
public:
    void unwrap_or_default() = delete;
};

template <class T>
class maybe_unwrap_or_default_injector<maybe<T>,
    std::enable_if_t<
        std::disjunction_v<
            std::is_default_constructible<T>,
            std::is_aggregate<T>>>>
{
public:
  T unwrap_or_default() const
  {
    if constexpr (std::is_aggregate_v<T>){
      return static_cast<maybe<T> const *>(this)->is_just()
        ? static_cast<maybe<T> const *>(this)->unwrap()
        : T{};
    }
    else {
      return static_cast<maybe<T> const *>(this)->is_just()
        ? static_cast<maybe<T> const *>(this)->unwrap()
        : T();
    }
  }
};

template <class> class maybe_flatten_injector {
public:
    void flatten() = delete;
};

template <class T>
class maybe_flatten_injector<maybe<maybe<T>>>
{
public:
    maybe<T>
    flatten() const& {
        return static_cast<maybe<maybe<T>>const*>(this)->is_just()
            && static_cast<maybe<maybe<T>>const*>(this)->unwrap().is_just()
                ? just(static_cast<maybe<maybe<T>>const*>(this)->unwrap().unwrap())
                : nothing<>;
    }
};

template <class, class=void> class maybe_copy_injector {
public:
    void copied() = delete;
    void replace() = delete;
};

template <class T>
class maybe_copy_injector<maybe<T>, std::enable_if_t<std::is_copy_constructible_v<T>>> {
public:
    maybe<T> copied() const& {
        return static_cast<maybe<T>const*>(this)->is_just()
            ? just<T>([](auto&& some) -> std::decay_t<decltype(some)> { return std::forward<decltype(some)>(some); }(static_cast<maybe<T>const*>(this)->unwrap()))
            : nothing<>;
    }

    maybe<T> replace(T value) & {
        auto old = static_cast<maybe<T>*>(this)->copied();
        if (!static_cast<maybe<T>*>(this)->storage_) {
            static_cast<maybe<T>*>(this)->storage_ = std::make_shared<mitamagic::maybe_view<boost::optional<T>>>(boost::optional<T>{value});
        }
        else {
            *(static_cast<maybe<T>*>(this)->storage_->get_pointer()) = value;
        }
        return old;
    }
};

template <class T>
class maybe
    : public maybe_transpose_injector<maybe<T>>
    , public maybe_unwrap_or_default_injector<maybe<T>>
    , public maybe_flatten_injector<maybe<T>>
    , public maybe_copy_injector<maybe<T>>
{
    std::shared_ptr<mitamagic::polymorphic_storage<T>> storage_;
    template<class, class>
    friend class maybe_copy_injector;
  public:
    using value_type = T;
    ~maybe() = default;
    maybe() = default;
    maybe(maybe const&) = default;
    maybe& operator=(maybe const&) = default;
    maybe(maybe&&) = default;
    maybe& operator=(maybe&&) = default;
    maybe(const nothing_t): maybe() {}

    template <typename U,
        std::enable_if_t<
            !std::is_base_of_v<mitama::in_place_factory_base, std::decay_t<U>> &&
            std::disjunction_v<
                mitamagic::is_pointer_like<std::remove_reference_t<U>>,
                std::is_pointer<std::remove_reference_t<U>>>, bool> = false>
    maybe(U&& u) : storage_(std::make_shared<mitamagic::maybe_view<U>>(std::forward<U>(u))) {}

    template <typename U,
        std::enable_if_t<
            std::conjunction_v<
                std::is_constructible<T, U&&>,
                std::negation<std::is_base_of<mitama::in_place_factory_base, std::decay_t<U>>>,
                std::disjunction<
                    mitamagic::is_pointer_like<std::remove_reference_t<U>>,
                    std::is_pointer<std::remove_reference_t<U>>>>,
        bool> = false>
    maybe(U&& u) : storage_(mitamagic::default_maybe_view<T>(std::forward<U>(u))) {}

    template <class... Args,
        std::enable_if_t<
            std::is_constructible_v<T, Args&&...>,
        bool> = false>
    explicit maybe(std::in_place_t, Args&&... args)
        : storage_(mitamagic::default_maybe_view<T>(std::forward<Args>(args)...)) {}

    template <class U, class... Args,
        std::enable_if_t<
            std::is_constructible_v<T, std::initializer_list<U>, Args&&...>,
        bool> = false>
    explicit maybe(std::in_place_t, std::initializer_list<U> il, Args&&... args)
        : storage_(mitamagic::default_maybe_view<T>(il, std::forward<Args>(args)...)) {}

    template <class InplaceFactory,
        std::enable_if_t<
            std::is_base_of_v<mitama::in_place_factory_base, std::decay_t<InplaceFactory>>,
        bool> = false>
    maybe(InplaceFactory&& factory)
        : storage_(std::forward<InplaceFactory>(factory).apply([](auto&&... args){
            return mitamagic::default_maybe_view<T>(std::forward<decltype(args)>(args)...);
        }))
    {}

    template <class F,
        std::enable_if_t<
            std::is_invocable_v<F&&, T&>,
        bool> = false>
    auto operator>>(F&& f) const& {
        static_assert(std::is_invocable_v<F&&, T&>,
            "specified functor is not invocable.");
        using result_type = std::remove_reference_t<std::invoke_result_t<F&&, T&>>;

        if constexpr (std::is_constructible_v<std::invoke_result_t<F&&, T&>, decltype(nullptr)>) {
            if ( this->is_just() ) {
                return maybe<typename mitamagic::element_type<std::decay_t<result_type>>::type>{std::invoke(std::forward<F>(f), storage_->deref())};
            }
            else {
                return maybe<typename mitamagic::element_type<std::decay_t<result_type>>::type>{result_type{nullptr}};
            }
        }
        else if constexpr (std::is_constructible_v<std::invoke_result_t<F&&, T&>, std::nullopt_t>) {
            if ( this->is_just() ) {
                return maybe<typename mitamagic::element_type<std::decay_t<result_type>>::type>{std::invoke(std::forward<F>(f), storage_->deref())};
            }
            else {
                return maybe<typename mitamagic::element_type<std::decay_t<result_type>>::type>{std::nullopt};
            }
        }
        else if constexpr (std::is_constructible_v<std::invoke_result_t<F&&, T&>, boost::none_t>) {
            if ( this->is_just() ) {
                return maybe<typename mitamagic::element_type<std::decay_t<result_type>>::type>{std::invoke(std::forward<F>(f), storage_->deref())};
            }
            else {
                return maybe<typename mitamagic::element_type<std::decay_t<result_type>>::type>{std::nullopt};
            }
        }
        else {
            if ( this->is_just() ) {
                return maybe<result_type>{boost::optional<result_type>(std::invoke(std::forward<F>(f), storage_->deref()))};
            }
            else {
                return maybe<result_type>{boost::optional<result_type>{boost::none}};
            }
        }
    }

    explicit operator bool() const {
        return this->is_just();
    }

    decltype(auto) operator->() & {
        return storage_->get_pointer();
    }

    decltype(auto) operator->() const& {
        return storage_->get_pointer();
    }

    bool is_just() const {
        return bool(storage_) && storage_->is_just();
    }

    bool is_nothing() const {
        return !this->is_just();
    }

    decltype(auto) unwrap() & {
        if (is_just())
            return storage_->deref();
        else
            PANIC("called `maybe::unwrap()` on a `nothing` value");
    }

    decltype(auto) unwrap() const& {
        if (is_just())
            return storage_->deref();
        else
            PANIC("called `maybe::unwrap()` on a `nothing` value");
    }

    T& get_or_insert(T const& v) & {
        if (!storage_) {
            storage_ = std::make_shared<mitamagic::maybe_view<boost::optional<T>>>(boost::optional<T>{v});
            return storage_->deref();
        }
        else {
            return this->is_just()
                ? storage_->deref()
                : (*storage_->get_pointer() = v);
        }
    }

    template <class F>
    std::enable_if_t<
        std::conjunction_v<
            std::is_invocable<F&&>,
            std::is_assignable<T&, std::invoke_result_t<F&&>>>,
    T&>
    get_or_insert_with(F&& f) & {
        if (!storage_) {
            storage_ = std::make_shared<mitamagic::maybe_view<boost::optional<T>>>(boost::optional<T>{std::invoke(std::forward<F>(f))});
            return storage_->deref();
        }
        else {
            return this->is_just()
                ? storage_->deref()
                : (*storage_->get_pointer() = std::invoke(std::forward<F>(f)));
        }
    }

    T unwrap_or(T const& def) const {
        return is_just() ? storage_->deref() : def;
    }

    template <class F>
    std::enable_if_t<
        std::is_invocable_r_v<T, F&&>,
    T>
    unwrap_or_else(F&& f) const {
        return is_just() ? storage_->deref() : std::invoke(std::forward<F>(f));
    }

    template <class F,
        std::enable_if_t<
            std::is_invocable_v<F&&, T&>, bool> = false>
    auto map(F&& f) const {
        return *this >> std::forward<F>(f);
    }

    template <class U, class F>
    std::enable_if_t<
        std::conjunction_v<
            std::is_invocable<F&&, T&>,
            meta::has_type<std::common_type<U&&, std::invoke_result_t<F&&, T&>>>>,
    std::common_type_t<U&&, std::invoke_result_t<F&&, T&>>>
    map_or(U&& def, F&& f) const {
        return is_just()
            ? std::invoke(std::forward<F>(f), storage_->deref())
            : std::forward<U>(def);
    }

    template <class D, class F>
    std::enable_if_t<
        std::conjunction_v<
            std::is_invocable<D&&>,
            std::is_invocable<F&&, T&>,
            meta::has_type<std::common_type<std::invoke_result_t<D&&>, std::invoke_result_t<F&&, T&>>>>,
    std::common_type_t<std::invoke_result_t<D&&>, std::invoke_result_t<F&&, T&>>>
    map_or_else(D&& def, F&& f) const {
        return is_just()
            ? std::invoke(std::forward<F>(f), storage_->deref())
            : std::invoke(std::forward<D>(def));
    }

    T& expect(std::string_view msg) {
        if (this->is_just()) {
            return this->unwrap();
        }
        else {
            PANIC("%1%: %2%", msg);
        }
    }

    template <class Pred,
        std::enable_if_t<
            std::is_invocable_r_v<bool, Pred&&, T&>, bool> = false>
    maybe filter(Pred&& predicate) const {
        return this->is_just() && std::invoke(std::forward<Pred>(predicate), storage_->deref())
            ? maybe(boost::optional<T>{storage_->deref()})
            : maybe(boost::optional<T>{boost::none});
    }

    template <class E = std::monostate>
    auto ok_or(E const& err = std::monostate{}) const {
        return this->is_just()
            ? result<T, E>{success{storage_->deref()}}
            : result<T, E>{failure{err}};
    }

    template <class F>
    std::enable_if_t<
        std::is_invocable_v<F&&>,
    result<T, std::invoke_result_t<F&&>>>
    ok_or_else(F&& err) const {
        return this->is_just()
            ? result<T, std::invoke_result_t<F&&>>{success{storage_->deref()}}
            : result<T, std::invoke_result_t<F&&>>{failure{std::invoke(std::forward<F>(err))}};
    }

    template <class F>
    std::enable_if_t<
        std::conjunction_v<
            std::is_invocable<F&&, T&>,
            is_maybe<std::decay_t<std::invoke_result_t<F&&, T&>>>>,
    std::invoke_result_t<F&&, T&> >
    and_then(F&& f) const {
        return this->is_just()
            ? std::invoke(std::forward<F>(f),storage_->deref())
            : nothing<>;
    }

    template <class F>
    std::enable_if_t<
        std::conjunction_v<
            std::is_invocable<F&&>,
            is_maybe_with<std::decay_t<std::invoke_result_t<F&&>>, T>>,
    maybe>
    or_else(F&& f) const {
        return this->is_just()
            ? just(unwrap())
            : std::invoke(std::forward<F>(f));
    }

    template <class F>
    std::enable_if_t<std::is_invocable_v<F&&, T&>>
    and_finally(F&& f) const& {
        if (this->is_just())
            std::invoke(std::forward<F>(f), storage_->deref());
    }
};

template <class T, class U>
std::enable_if_t<meta::is_comparable_with<T, U>::value,
bool>
operator==(maybe<T> const& lhs, maybe<U> const& rhs) {
    return lhs && rhs && (lhs.unwrap() == rhs.unwrap());
}

template <class T, class U>
std::enable_if_t<meta::is_comparable_with<T, U>::value,
bool>
operator!=(maybe<T> const& lhs, maybe<U> const& rhs) {
    return !(lhs == rhs);
}

template <class T>
bool operator==(maybe<T> const& lhs, const nothing_t) {
    return lhs.is_nothing();
}

template <class T>
bool operator==(const nothing_t, maybe<T> const& rhs) {
    return rhs.is_nothing();
}

template <class T>
bool operator!=(maybe<T> const& lhs, const nothing_t) {
    return lhs.is_just();
}

template <class T>
bool operator!=(const nothing_t, maybe<T> const& rhs) {
    return rhs.is_just();
}

template <class T, class U>
bool operator<(maybe<T> const& lhs, maybe<U> const& rhs) {
    return lhs.ok_or() < rhs.ok_or();
}

template <class T, class U>
bool operator<=(maybe<T> const& lhs, maybe<U> const& rhs) {
    return lhs.ok_or() <= rhs.ok_or();
}

template <class T, class U>
bool operator>(maybe<T> const& lhs, maybe<U> const& rhs) {
    return lhs.ok_or() > rhs.ok_or();
}

template <class T, class U>
bool operator>=(maybe<T> const& lhs, maybe<U> const& rhs) {
    return lhs.ok_or() >= rhs.ok_or();
}

/// @brief
///   ostream output operator for maybe<T>
///
/// @requires
///   Format<T>;
///
/// @note
///   Output its contained value with pretty format, and is used by `operator<<` found by ADL.
template <class T>
std::enable_if_t<trait::formattable<T>::value,
std::ostream&>
operator<<(std::ostream& os, maybe<T> const& may) {
  using namespace std::string_literals;
  using namespace std::string_view_literals;
  auto inner_format = boost::hana::fix(boost::hana::overload_linearly(
      [](auto, auto const& x) -> std::enable_if_t<trait::formattable_element<std::decay_t<decltype(x)>>::value, std::string> {
        return boost::hana::overload_linearly(
          [](std::monostate) { return "()"s; },
          [](std::string_view x) { return (boost::format("\"%1%\"") % x).str(); },
          [](auto const& x) { return (boost::format("%1%") % x).str(); })
        (x);
      },
      [](auto _fmt, auto const& x) -> std::enable_if_t<trait::formattable_dictionary<std::decay_t<decltype(x)>>::value, std::string> {
        if (x.empty()) return "{}"s;
        using std::begin, std::end;
        auto iter = begin(x);
        std::string str = "{"s + (boost::format("%1%: %2%") % _fmt(std::get<0>(*iter)) % _fmt(std::get<1>(*iter))).str();
        while (++iter != end(x)) {
          str += (boost::format(",%1%: %2%") % _fmt(std::get<0>(*iter)) % _fmt(std::get<1>(*iter))).str();
        }
        return str += "}";
      },
      [](auto _fmt, auto const& x) -> std::enable_if_t<trait::formattable_range<std::decay_t<decltype(x)>>::value, std::string> {
        if (x.empty()) return "[]"s;
        using std::begin, std::end;
        auto iter = begin(x);
        std::string str = "["s + _fmt(*iter);
        while (++iter != end(x)) {
          str += (boost::format(",%1%") % _fmt(*iter)).str();
        }
        return str += "]";
      },
      [](auto _fmt, auto const& x) -> std::enable_if_t<trait::formattable_tuple<std::decay_t<decltype(x)>>::value, std::string> {
        if constexpr (std::tuple_size_v<std::decay_t<decltype(x)>> == 0) {
          return "()"s;
        }
        else {
          return std::apply(
            [_fmt](auto const& head, auto const&... tail) {
              return "("s + _fmt(head) + ((("," + _fmt(tail))) + ...) + ")"s;
            }, x);
        }
      }));
  return may.is_just() ? os << boost::format("just(%1%)") % inner_format( may.unwrap() )
                       : os << "nothing"sv;
}

template <class T> maybe(T&&) -> maybe<typename mitamagic::element_type<std::decay_t<T>>::type>;

}
#endif

max_stars_repo_name: agate-pris/mitama-cpp-result

max_issues_repo_name: agate-pris/mitama-cpp-result

max_forks_repo_name: agate-pris/mitama-cpp-result


text:
/*=============================================================================
    Copyright (c) 2010 Christopher Schmidt

    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)
==============================================================================*/

#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/iterator.hpp>
#include <boost/fusion/algorithm/transformation/reverse.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/fusion/algorithm/iteration/reverse_fold.hpp>
#include <boost/fusion/algorithm/iteration/iter_fold.hpp>
#include <boost/fusion/algorithm/iteration/reverse_iter_fold.hpp>
#include <boost/fusion/container/vector/convert.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/support/pair.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <iostream>

namespace mpl=boost::mpl;
namespace fusion=boost::fusion;

#ifdef BOOST_FUSION_TEST_REVERSE_FOLD
#   ifdef BOOST_FUSION_TEST_ITER_FOLD
#       define BOOST_FUSION_TEST_FOLD_NAME reverse_iter_fold
#   else
#       define BOOST_FUSION_TEST_FOLD_NAME reverse_fold
#   endif
#else
#   ifdef BOOST_FUSION_TEST_ITER_FOLD
#       define BOOST_FUSION_TEST_FOLD_NAME iter_fold
#   else
#       define BOOST_FUSION_TEST_FOLD_NAME fold
#   endif
#endif

struct sum
{
    template<typename Sig>
    struct result;

    template<typename Self, typename State, typename T>
    struct result<Self(State,T)>
      : boost::fusion::result_of::make_pair<
            mpl::int_<
                boost::remove_reference<
                    State
                >::type::first_type::value+1
            >
          , int
        >
    {
        BOOST_MPL_ASSERT((typename boost::is_reference<State>::type));
        BOOST_MPL_ASSERT((typename boost::is_reference<T>::type));
    };

#ifdef BOOST_FUSION_TEST_ITER_FOLD
    template<typename State, typename It>
    typename result<sum const&(State const&,It const&)>::type
    operator()(State const& state, It const& it)const
    {
        static const int n=State::first_type::value;
        return fusion::make_pair<mpl::int_<n+1> >(
            state.second+fusion::deref(it)*n);
    }
#else
    template<typename State>
    typename result<sum const&(State const&, int const&)>::type
    operator()(State const& state, int const& e)const
    {
        static const int n=State::first_type::value;
        return fusion::make_pair<mpl::int_<n+1> >(state.second+e*n);
    }
#endif
};

struct meta_sum
{
    template<typename Sig>
    struct result;

    template<typename Self, typename State, typename T>
    struct result<Self(State,T)>
    {
        BOOST_MPL_ASSERT((typename boost::is_reference<State>::type));
        BOOST_MPL_ASSERT((typename boost::is_reference<T>::type));

        typedef typename boost::remove_reference<State>::type state;
        static const int n=mpl::front<state>::type::value;

#ifdef BOOST_FUSION_TEST_ITER_FOLD
        typedef typename
            boost::fusion::result_of::value_of<
                typename boost::remove_reference<T>::type
            >::type
        t;
#else
        typedef typename boost::remove_reference<T>::type t;
#endif

        typedef
            mpl::vector<
                mpl::int_<n+1>
              , mpl::int_<
                    mpl::back<state>::type::value+t::value*n
                >
            >
        type;
    };

    template<typename State, typename T>
    typename result<meta_sum const&(State const&,T const&)>::type
    operator()(State const&, T const&)const;
};

struct fold_test_n
{
    template<typename I>
    void
    operator()(I)const
    {
        static const int n=I::value;
        typedef mpl::range_c<int, 0, n> range;

        static const int squares_sum=n*(n+1)*(2*n+1)/6;

        {
            mpl::range_c<int, 1, n+1> init_range;
            typename boost::fusion::result_of::as_vector<
                typename mpl::transform<
                    range
                  , mpl::always<int>
                  , mpl::back_inserter<mpl::vector<> >
                >::type
            >::type vec(
#ifdef BOOST_FUSION_TEST_REVERSE_FOLD
                fusion::reverse(init_range)
#else
                init_range
#endif
            );

            int result=BOOST_FUSION_TEST_FOLD_NAME(
                vec,
                fusion::make_pair<mpl::int_<1> >(0),
                sum()).second;
            std::cout << n << ": " << result << std::endl;
            BOOST_TEST(result==squares_sum);
        }

        {
            typedef typename
#ifdef BOOST_FUSION_TEST_REVERSE_FOLD
                boost::fusion::result_of::as_vector<
                    typename mpl::copy<
                        mpl::range_c<int, 1, n+1>
                      , mpl::front_inserter<fusion::vector<> >
                    >::type
                >::type
#else
                boost::fusion::result_of::as_vector<mpl::range_c<int, 1, n+1> >::type
#endif
            vec;

            typedef
                boost::is_same<
                    typename boost::fusion::result_of::BOOST_FUSION_TEST_FOLD_NAME<
                        vec
                      , mpl::vector<mpl::int_<1>, mpl::int_<0> >
                      , meta_sum
                    >::type
                  , typename mpl::if_c<
                        !n
                      , mpl::vector<mpl::int_<1>, mpl::int_<0> >&
                      , mpl::vector<mpl::int_<n+1>, mpl::int_<squares_sum> >
                    >::type
                >
            result_test;

            BOOST_MPL_ASSERT((result_test));
        }
    }
};

int
main()
{
    mpl::for_each<mpl::range_c<int, 0, 10> >(fold_test_n());

    return boost::report_errors();
}

#undef BOOST_FUSION_TEST_FOLD_NAME


text:
#include "testlauncher.h"
#include "testreporter.h"
#include "test.h"
#include "sectionsreader.h"
#include "utils.h"
#include <boost/algorithm/string.hpp>
#include <fstream>

TestLauncher::TestLauncher(const fs::path& testPath,
                           const std::string& testFileExt,
                           const TestReporter& reporter)
    : reporter_(reporter)
{
    collectTests(testPath, testFileExt);
}

bool TestLauncher::process()
{
    auto ok = processSuite("", defaultSuite_);
    for (auto& suitePair : suites_)
        if (!processSuite(suitePair.first, suitePair.second))
            ok = false;
    reporter_.reportSummary(defaultSuite_, suites_);
    return ok;
}

bool TestLauncher::processSuite(const std::string& suiteName, TestSuite& suite)
{
    const auto& tests = suite.tests;
    const auto testsCount = static_cast<int>(tests.size());
    auto testNumber = 0;
    bool ok = true;
    for (const auto& testCfg : tests){
        testNumber++;
        try{
            auto test = Test{testCfg.path};
            if (!testCfg.isEnabled){
                reporter_.reportDisabledTest(test, suiteName, testNumber, testsCount);
                continue;
            }
            auto result = test.process();
            if (result.type() == TestResultType::Success)
                suite.passedTestsCounter++;
            else
                ok = false;
            reporter_.reportResult(test, result, suiteName, testNumber, testsCount);

        }
        catch(const TestConfigError& error){
            reporter_.reportBrokenTest(testCfg.path, error.what(), suiteName, testNumber, testsCount);
            ok = false;
        }
    }
    return ok;
}

void TestLauncher::collectTests(const fs::path &testPath, const std::string& testFileExt)
{
    if (fs::is_directory(testPath)){
        if (testFileExt.empty())
            throw std::runtime_error{"To launch all tests in the directory, test extension must be specified"};

        auto end = fs::directory_iterator{};
        for (auto it = fs::directory_iterator{testPath}; it != end; ++it)
            if (fs::is_directory(it->status()))
                collectTests(it->path(), testFileExt);
            else if(it->path().extension().string() == testFileExt)
                addTest(fs::canonical(it->path()));
    }
    else
        addTest(fs::canonical(testPath));
}

void TestLauncher::addTest(const fs::path &testFile)
{
    auto stream = std::ifstream{testFile.string()};
    auto enabledStr = boost::to_lower_copy(boost::trim_copy(readSectionValue(stream, "Enabled")));
    auto isEnabled = (enabledStr.empty() || enabledStr == "true");
    stream.clear();
    stream.seekg(0, std::ios::beg);
    auto suiteName = boost::trim_copy(readSectionValue(stream, "Suite"));
    processVariablesSubstitution(suiteName, testFile.stem().string(), testFile.parent_path().stem().string());

    if (suiteName.empty()){
        defaultSuite_.tests.push_back({testFile, isEnabled});
        if (!isEnabled)
            defaultSuite_.disabledTestsCounter++;
    }
    else{
        suites_[suiteName].tests.push_back({testFile, isEnabled});
        if (!isEnabled)
            suites_[suiteName].disabledTestsCounter++;
    }
}

max_stars_repo_name: kamchatka-volcano/lunchtoast

max_issues_repo_name: kamchatka-volcano/lunchtoast

max_forks_repo_name: kamchatka-volcano/lunchtoast


text:
#include "core/dataset/tensor_dataset.hpp"
#include <boost/program_options.hpp>
namespace po = boost::program_options;

int main(int argc, char **argv) {
    //
    logger_impl logger;
    std::string data_dir, dtype;
    int batch_size, img_size,
        num_prefetchers, prefetch_pool_size,
        num_warmup_batches, num_batches;
    // Parse command line options
    po::options_description opt_desc("Benchmark Tensor Datasets");
    po::variables_map var_map;
    opt_desc.add_options()
        ("help", "Print help message")
        ("data_dir", po::value<std::string>(&data_dir)->required(), "Path to a dataset to use.")
        ("batch_size", po::value<int>(&batch_size)->default_value(512), "Batch size.")
        ("img_size", po::value<int>(&img_size)->default_value(227), "Size of images in a dataset (width = height).")
        ("num_prefetchers", po::value<int>(&num_prefetchers)->default_value(1), "Number of prefetchers (readers).")
        ("prefetch_pool_size", po::value<int>(&prefetch_pool_size)->default_value(2), "Number of pre-allocated batches.")
        ("num_warmup_batches", po::value<int>(&num_warmup_batches)->default_value(10), "Number of warmup iterations.")
        ("num_batches", po::value<int>(&num_batches)->default_value(50), "Number of benchmark iterations.")
        ("dtype", po::value<std::string>(&dtype)->default_value("float"), "Tensor data type - 'float' or 'uchar'.");
    //
    try {
        po::store(po::parse_command_line(argc, argv, opt_desc), var_map);
        if (var_map.count("help")) {
            std::cout << opt_desc << std::endl;
            return 0;
        }
        po::notify(var_map);
    } catch(po::error& e) {
        logger.log_warning(e.what());
        std::cout << opt_desc << std::endl;
        logger.log_error("Cannot recover from previous errors");
    }
    //
    logger.log_info(fmt(
        "[benchmarks            ]: data_dir=%s, batch_size=%d, img_size=%d, num_prefetchers=%d, prefetch_pool_size=%d, num_warmup_batches=%d, num_batches=%d, dtype=%s",
        data_dir.c_str(), batch_size, img_size, num_prefetchers, prefetch_pool_size, num_warmup_batches, num_batches, dtype.c_str()
    ));
    const auto images_sec = tensor_dataset::benchmark(
        data_dir, batch_size, img_size, num_prefetchers, prefetch_pool_size,
        num_warmup_batches, num_batches, dtype
    );
    if (images_sec >= 0) {
        // 3 channels times number of elements per channel times element size in bytes devided by bytes in megabyte
        const float img_mb = float(3*img_size*img_size)*(dtype == "float" ? 4 : 1) / (1024*1024);
        const float mb_sec = images_sec * img_mb;
        logger.log_info(fmt("[benchmarks            ]: images/sec=%f, MB/sec=%f", images_sec, mb_sec));
    } else {
        logger.log_warning("[benchmarks            ]: Benchmark returned error code indicating there was an error.");
    }

}

max_stars_repo_name: tfindlay-au/dlcookbook-dlbs

max_issues_repo_name: tfindlay-au/dlcookbook-dlbs

max_forks_repo_name: tfindlay-au/dlcookbook-dlbs


text:
/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the LICENSE
 * file in the root directory of this source tree.
 */
#include "bistro/bistro/utils/shell.h"

#include <boost/algorithm/string.hpp>
#include <folly/String.h>

namespace facebook { namespace bistro {

const std::string escapeShellArgsInsecure(
    const std::vector<std::string>& cmd) {

  std::vector<std::string> escaped_cmd;
  for (const auto& arg : cmd) {
    escaped_cmd.push_back(arg);
    boost::replace_all(escaped_cmd.back(), "'", "'\\''");
  }
  return "'" + folly::join("' '", escaped_cmd) + "'";
}

}}

max_stars_repo_name: fakeNetflix/facebook-repo-bistro

max_issues_repo_name: fakeNetflix/facebook-repo-bistro

max_forks_repo_name: fakeNetflix/facebook-repo-bistro


text:
#include "camodocal/calib/HandEyeCalibration.h"

#include <boost/throw_exception.hpp>
#include <iostream>

#include <ceres/ceres.h>
#include "camodocal/EigenUtils.h"
#include "camodocal/calib/DualQuaternion.h"

namespace camodocal {

/// @todo there may be an alignment issue, see
/// http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html
class PoseError {
  public:
    PoseError(Eigen::Vector3d r1, Eigen::Vector3d t1, Eigen::Vector3d r2,
              Eigen::Vector3d t2)
        : m_rvec1(r1), m_rvec2(r2), m_tvec1(t1), m_tvec2(t2) {}

    template <typename T>
    bool operator()(const T* const q4x1, const T* const t3x1,
                    T* residual) const {
        Eigen::Quaternion<T> q(q4x1[0], q4x1[1], q4x1[2], q4x1[3]);
        Eigen::Matrix<T, 3, 1> t;
        t << t3x1[0], t3x1[1], t3x1[2];

        DualQuaternion<T> dq(q, t);

        Eigen::Matrix<T, 3, 1> r1 = m_rvec1.cast<T>();
        Eigen::Matrix<T, 3, 1> t1 = m_tvec1.cast<T>();
        Eigen::Matrix<T, 3, 1> r2 = m_rvec2.cast<T>();
        Eigen::Matrix<T, 3, 1> t2 = m_tvec2.cast<T>();

        DualQuaternion<T> dq1(AngleAxisToQuaternion<T>(r1), t1);
        DualQuaternion<T> dq2(AngleAxisToQuaternion<T>(r2), t2);
        DualQuaternion<T> dq1_ = dq * dq2 * dq.inverse();

        DualQuaternion<T> diff = (dq1.inverse() * dq1_).log();
        residual[0] = diff.real().squaredNorm() + diff.dual().squaredNorm();

        return true;
    }

  private:
    Eigen::Vector3d m_rvec1, m_rvec2, m_tvec1, m_tvec2;

  public:
    /// @see
    /// http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

bool HandEyeCalibration::mVerbose = true;

HandEyeCalibration::HandEyeCalibration() {}

void HandEyeCalibration::setVerbose(bool on) { mVerbose = on; }

/// Reorganize data to prepare for running SVD
/// Daniilidis 1999 Section 6, Equations (31) and (33), on page 291
template <typename T>
static Eigen::MatrixXd ScrewToStransposeBlockofT(
    const Eigen::Matrix<T, 3, 1>& a, const Eigen::Matrix<T, 3, 1>& a_prime,
    const Eigen::Matrix<T, 3, 1>& b, const Eigen::Matrix<T, 3, 1>& b_prime) {
    Eigen::MatrixXd Stranspose(6, 8);
    Stranspose.setZero();

    typedef Eigen::Matrix<T, 3, 1> VecT;
    auto skew_a_plus_b = skew(VecT(a + b));
    auto a_minus_b = a - b;
    Stranspose.block<3, 1>(0, 0) = a_minus_b;
    Stranspose.block<3, 3>(0, 1) = skew_a_plus_b;
    Stranspose.block<3, 1>(3, 0) = a_prime - b_prime;
    Stranspose.block<3, 3>(3, 1) = skew(VecT(a_prime + b_prime));
    Stranspose.block<3, 1>(3, 4) = a_minus_b;
    Stranspose.block<3, 3>(3, 5) = skew_a_plus_b;

    return Stranspose;
}

/// Reorganize data to prepare for running SVD
/// Daniilidis 1999 Section 6, Equations (31) and (33), on page 291
// @pre no zero rotations, thus (rvec1.norm() != 0 && rvec2.norm() != 0) == true
template <typename T>
static Eigen::MatrixXd AxisAngleToSTransposeBlockOfT(
    const Eigen::Matrix<T, 3, 1>& rvec1, const Eigen::Matrix<T, 3, 1>& tvec1,
    const Eigen::Matrix<T, 3, 1>& rvec2, const Eigen::Matrix<T, 3, 1>& tvec2) {
    double theta1, d1;
    Eigen::Vector3d l1, m1;
    AngleAxisAndTranslationToScrew(rvec1, tvec1, theta1, d1, l1, m1);

    double theta2, d2;
    Eigen::Vector3d l2, m2;
    AngleAxisAndTranslationToScrew(rvec2, tvec2, theta2, d2, l2, m2);

    Eigen::Vector3d a = l1;
    Eigen::Vector3d a_prime = m1;
    Eigen::Vector3d b = l2;
    Eigen::Vector3d b_prime = m2;

    return ScrewToStransposeBlockofT(a, a_prime, b, b_prime);
}

// docs in header
void HandEyeCalibration::estimateHandEyeScrew(
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs2,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs2,
    Eigen::Matrix4d& H_12, bool planarMotion) {
    int motionCount = rvecs1.size();
    Eigen::MatrixXd T(motionCount * 6, 8);
    T.setZero();

    for (size_t i = 0; i < motionCount; ++i) {
        const Eigen::Vector3d& rvec1 = rvecs1.at(i);
        const Eigen::Vector3d& tvec1 = tvecs1.at(i);
        const Eigen::Vector3d& rvec2 = rvecs2.at(i);
        const Eigen::Vector3d& tvec2 = tvecs2.at(i);

        // Skip cases with zero rotation
        if (rvec1.norm() == 0 || rvec2.norm() == 0)
            continue;

        T.block<6, 8>(i * 6, 0) =
            AxisAngleToSTransposeBlockOfT(rvec1, tvec1, rvec2, tvec2);
    }

    auto dq = estimateHandEyeScrewInitial(T, planarMotion);

    H_12 = dq.toMatrix();
    if (mVerbose) {
        std::cout << "# INFO: Before refinement: H_12 = " << std::endl;
        std::cout << H_12 << std::endl;
    }

    estimateHandEyeScrewRefine(dq, rvecs1, tvecs1, rvecs2, tvecs2);

    H_12 = dq.toMatrix();
    if (mVerbose) {
        std::cout << "# INFO: After refinement: H_12 = " << std::endl;
        std::cout << H_12 << std::endl;
    }
}

// docs in header
void HandEyeCalibration::estimateHandEyeScrew(
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs2,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs2,
    Eigen::Matrix4d& H_12, ceres::Solver::Summary& summary, bool planarMotion) {
    int motionCount = rvecs1.size();
    Eigen::MatrixXd T(motionCount * 6, 8);
    T.setZero();

    for (size_t i = 0; i < motionCount; ++i) {
        const Eigen::Vector3d& rvec1 = rvecs1.at(i);
        const Eigen::Vector3d& tvec1 = tvecs1.at(i);
        const Eigen::Vector3d& rvec2 = rvecs2.at(i);
        const Eigen::Vector3d& tvec2 = tvecs2.at(i);

        // Skip cases with zero rotation
        if (rvec1.norm() == 0 || rvec2.norm() == 0)
            continue;

        T.block<6, 8>(i * 6, 0) =
            AxisAngleToSTransposeBlockOfT(rvec1, tvec1, rvec2, tvec2);
    }

    auto dq = estimateHandEyeScrewInitial(T, planarMotion);

    H_12 = dq.toMatrix();
    if (mVerbose) {
        std::cout << "# INFO: Before refinement: H_12 = " << std::endl;
        std::cout << H_12 << std::endl;
    }

    estimateHandEyeScrewRefine(dq, rvecs1, tvecs1, rvecs2, tvecs2, summary);

    H_12 = dq.toMatrix();
    if (mVerbose) {
        std::cout << "# INFO: After refinement: H_12 = " << std::endl;
        std::cout << H_12 << std::endl;
    }
}

// docs in header
DualQuaterniond
HandEyeCalibration::estimateHandEyeScrewInitial(Eigen::MatrixXd& T,
                                                bool planarMotion) {

    // dq(r1, t1) = dq * dq(r2, t2) * dq.inv
    Eigen::JacobiSVD<Eigen::MatrixXd> svd(T, Eigen::ComputeFullU |
                                                 Eigen::ComputeFullV);

    // v7 and v8 span the null space of T, v6 may also be one
    // if rank = 5.
    Eigen::Matrix<double, 8, 1> v6 = svd.matrixV().block<8, 1>(0, 5);
    Eigen::Matrix<double, 8, 1> v7 = svd.matrixV().block<8, 1>(0, 6);
    Eigen::Matrix<double, 8, 1> v8 = svd.matrixV().block<8, 1>(0, 7);

    // if rank = 5
    if (planarMotion) //(rank == 5)
    {
        if (mVerbose) {
            std::cout
                << "# INFO: No unique solution, returned an arbitrary one. "
                << std::endl;
        }

        v7 += v6;
    }

    Eigen::Vector4d u1 = v7.block<4, 1>(0, 0);
    Eigen::Vector4d v1 = v7.block<4, 1>(4, 0);
    Eigen::Vector4d u2 = v8.block<4, 1>(0, 0);
    Eigen::Vector4d v2 = v8.block<4, 1>(4, 0);

    double lambda1 = 0;
    double lambda2 = 0.0;

    if (u1.dot(v1) == 0.0) {
        std::swap(u1, u2);
        std::swap(v1, v2);
    }
    if (u1.dot(v1) != 0.0) {
        double s[2];
        solveQuadraticEquation(u1.dot(v1), u1.dot(v2) + u2.dot(v1), u2.dot(v2),
                               s[0], s[1]);

        // find better solution for s
        double t[2];
        for (int i = 0; i < 2; ++i) {
            t[i] =
                s[i] * s[i] * u1.dot(u1) + 2 * s[i] * u1.dot(u2) + u2.dot(u2);
        }

        int idx;
        if (t[0] > t[1]) {
            idx = 0;
        } else {
            idx = 1;
        }

        double discriminant =
            4.0 * square(u1.dot(u2)) - 4.0 * (u1.dot(u1) * u2.dot(u2));
        if (discriminant == 0.0 && mVerbose) {
            //            std::cout << "# INFO: Noise-free case" << std::endl;
        }

        lambda2 = sqrt(1.0 / t[idx]);
        lambda1 = s[idx] * lambda2;
    } else {
        if (u1.norm() == 0 && u2.norm() > 0) {
            lambda1 = 0;
            lambda2 = 1.0 / u2.norm();
        } else if (u2.norm() == 0 && u1.norm() > 0) {
            lambda1 = 1.0 / u1.norm();
            lambda2 = 0;
        } else {
            std::ostringstream ss;

            ss << "camodocal::HandEyeCalibration error: normalization could "
                  "not be handled. Your rotations and translations are "
                  "probably either not aligned or not passed in properly.";
            ss << "u1:" << std::endl;
            ss << u1 << std::endl;
            ss << "v1:" << std::endl;
            ss << v1 << std::endl;
            ss << "u2:" << std::endl;
            ss << u2 << std::endl;
            ss << "v2:" << std::endl;
            ss << v2 << std::endl;
            ss << "Not handled yet. Your rotations and translations are "
                  "probably either not aligned or not passed in properly."
               << std::endl;

            BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
        }
    }

    // rotation
    Eigen::Vector4d q_coeffs = lambda1 * u1 + lambda2 * u2;
    Eigen::Vector4d q_prime_coeffs = lambda1 * v1 + lambda2 * v2;

    Eigen::Quaterniond q(q_coeffs(0), q_coeffs(1), q_coeffs(2), q_coeffs(3));
    Eigen::Quaterniond d(q_prime_coeffs(0), q_prime_coeffs(1),
                         q_prime_coeffs(2), q_prime_coeffs(3));

    return DualQuaterniond(q, d);
}

// docs in header
bool HandEyeCalibration::solveQuadraticEquation(double a, double b, double c,
                                                double& x1, double& x2) {
    double delta2 = b * b - 4.0 * a * c;

    if (delta2 < 0.0) {
        return false;
    }

    double delta = sqrt(delta2);

    x1 = (-b + delta) / (2.0 * a);
    x2 = (-b - delta) / (2.0 * a);

    return true;
}

// docs in header
void HandEyeCalibration::estimateHandEyeScrewRefine(
    DualQuaterniond& dq,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs2,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs2,
    ceres::Solver::Summary& summary) {
    Eigen::Matrix4d H = dq.toMatrix();
    double p[7] = {dq.real().w(), dq.real().x(), dq.real().y(), dq.real().z(),
                   H(0, 3),       H(1, 3),       H(2, 3)};

    ceres::Problem problem;
    for (size_t i = 0; i < rvecs1.size(); i++) {
        // ceres deletes the objects allocated here for the user
        ceres::CostFunction* costFunction =
            new ceres::AutoDiffCostFunction<PoseError, 1, 4, 3>(
                new PoseError(rvecs1[i], tvecs1[i], rvecs2[i], tvecs2[i]));

        problem.AddResidualBlock(costFunction, NULL, p, p + 4);
    }

    // ceres deletes the object allocated here for the user
    ceres::LocalParameterization* quaternionParameterization =
        new ceres::QuaternionParameterization;

    problem.SetParameterization(p, quaternionParameterization);

    ceres::Solver::Options options;
    options.linear_solver_type = ceres::DENSE_QR;
    options.jacobi_scaling = true;
    options.max_num_iterations = 500;

    // ceres::Solver::Summary summary;
    ceres::Solve(options, &problem, &summary);

    if (mVerbose) {
        std::cout << summary.BriefReport() << std::endl;
    }

    Eigen::Quaterniond q(p[0], p[1], p[2], p[3]);
    Eigen::Vector3d t;
    t << p[4], p[5], p[6];
    dq = DualQuaterniond(q, t);
}

void HandEyeCalibration::estimateHandEyeScrewRefine(
    DualQuaterniond& dq,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs1,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& rvecs2,
    const std::vector<Eigen::Vector3d,
                      Eigen::aligned_allocator<Eigen::Vector3d>>& tvecs2) {
    Eigen::Matrix4d H = dq.toMatrix();
    double p[7] = {dq.real().w(), dq.real().x(), dq.real().y(), dq.real().z(),
                   H(0, 3),       H(1, 3),       H(2, 3)};
    ceres::Solver::Summary summary;

    ceres::Problem problem;
    for (size_t i = 0; i < rvecs1.size(); i++) {
        // ceres deletes the objects allocated here for the user
        ceres::CostFunction* costFunction =
            new ceres::AutoDiffCostFunction<PoseError, 1, 4, 3>(
                new PoseError(rvecs1[i], tvecs1[i], rvecs2[i], tvecs2[i]));

        problem.AddResidualBlock(costFunction, NULL, p, p + 4);
    }

    // ceres deletes the object allocated here for the user
    ceres::LocalParameterization* quaternionParameterization =
        new ceres::QuaternionParameterization;

    problem.SetParameterization(p, quaternionParameterization);

    ceres::Solver::Options options;
    options.linear_solver_type = ceres::DENSE_QR;
    options.jacobi_scaling = true;
    options.max_num_iterations = 500;

    // ceres::Solver::Summary summary;
    ceres::Solve(options, &problem, &summary);

    if (mVerbose) {
        std::cout << summary.BriefReport() << std::endl;
    }

    Eigen::Quaterniond q(p[0], p[1], p[2], p[3]);
    Eigen::Vector3d t;
    t << p[4], p[5], p[6];
    dq = DualQuaterniond(q, t);
}
}

ext: cc


text:
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2004-2007 Jonathan Turkanis
// 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.)

// See http://www.boost.org/libs/iostreams for documentation.

// Contains the definitions of two codecvt facets useful for testing code
// conversion. Both represent the "null padded" character encoding described as
// follows. A wide character can be represented by the encoding if its value V
// is within the range of an unsigned char. The first char of the sequence
// representing V is V % 3 + 1. This is followed by V % 3 null characters, and
// finally by V itself.

// The first codecvt facet, null_padded_codecvt, is statefull, with state_type
// equal to int.

// The second codecvt facet, stateless_null_padded_codecvt, is stateless. At
// each point in a conversion, no characters are consumed unless there is room
// in the output sequence to write an entire multibyte sequence.

#ifndef BOOST_IOSTREAMS_TEST_NULL_PADDED_CODECVT_HPP_INCLUDED
#define BOOST_IOSTREAMS_TEST_NULL_PADDED_CODECVT_HPP_INCLUDED

#include <boost/config.hpp>                          // NO_STDC_NAMESPACE
#include <boost/iostreams/detail/codecvt_helper.hpp>
#include <boost/iostreams/detail/config/wide_streams.hpp>
#include <cstddef>                                   // mbstate_t.
#include <locale>                                    // codecvt.
#include <boost/integer_traits.hpp>                  // const_max.

#ifdef BOOST_NO_STDC_NAMESPACE
    namespace std { using ::mbstate_t; }
#endif

namespace boost { namespace iostreams { namespace test {

//------------------Definition of null_padded_codecvt_state-------------------//

class null_padded_codecvt_state {
public:
    null_padded_codecvt_state(int val = 0) : val_(val) { }
    operator int() const { return val_; }
    int& val() { return val_; }
    const int& val() const { return val_; }
private:
    int val_;
};

} } }

BOOST_IOSTREAMS_CODECVT_SPEC(boost::iostreams::test::null_padded_codecvt_state)

namespace boost { namespace iostreams { namespace test {

//------------------Definition of null_padded_codevt--------------------------//

//
// state is initially 0. After a single character is consumed, state is set to
// the number of characters in the current multibyte sequence and decremented
// as each character is consumed until its value reaches 0 again.
//
class null_padded_codecvt
    : public iostreams::detail::codecvt_helper<
                 wchar_t, char, null_padded_codecvt_state
             >
{
public:
    typedef null_padded_codecvt_state state_type;
private:
    std::codecvt_base::result
    do_in( state_type& state, const char* first1, const char* last1,
           const char*& next1, wchar_t* first2, wchar_t* last2,
           wchar_t*& next2 ) const
    {
        using namespace std;
        if (state < 0 || state > 3)
            return codecvt_base::error;
        next1 = first1;
        next2 = first2;
        while (next2 != last2 && next1 != last1) {
            while (next1 != last1) {
                if (state == 0) {
                    if (*next1 < 1 || *next1 > 3)
                        return codecvt_base::error;
                    state = *next1++;
                } else if (state == 1) {
                    *next2++ = (unsigned char) *next1++;
                    state = 0;
                    break;
                } else {
                    if (*next1++ != 0)
                        return codecvt_base::error;
                    --state.val();
                }
            }
        }
        return next2 == last2 ?
            codecvt_base::ok :
            codecvt_base::partial;
    }

    std::codecvt_base::result
    do_out( state_type& state, const wchar_t* first1, const wchar_t* last1,
            const wchar_t*& next1, char* first2, char* last2,
            char*& next2 ) const
    {
        using namespace std;
        if (state < 0 || state > 3)
            return codecvt_base::error;
        next1 = first1;
        next2 = first2;
        while (next1 != last1 && next2 != last2) {
            while (next2 != last2) {
                if (state == 0) {
                    if (*next1 > integer_traits<unsigned char>::const_max)
                        return codecvt_base::noconv;
                    state = *next1 % 3 + 1;
                    *next2++ = static_cast<char>(state);
                } else if (state == 1) {
                    state = 0;
                    *next2++ = static_cast<unsigned char>(*next1++);
                    break;
                } else {
                    --state.val();
                    *next2++ = 0;
                }
            }
        }
        return next1 == last1 ?
            codecvt_base::ok :
            codecvt_base::partial;
    }

    std::codecvt_base::result
    do_unshift( state_type& state,
                char* /* first2 */,
                char* last2,
                char*& next2 ) const
    {
        using namespace std;
        next2 = last2;
        while (state.val()-- > 0)
            if (next2 != last2)
                *next2++ = 0;
            else
                return codecvt_base::partial;
        return codecvt_base::ok;
    }

    bool do_always_noconv() const throw() { return false; }

    int do_max_length() const throw() { return 4; }

    int do_encoding() const throw() { return -1; }

    int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER state_type& state,
                   const char* first1, const char* last1,
                   std::size_t len2 ) const throw()
    {   // Implementation should follow that of do_in().
        int st = state;
        std::size_t result = 0;
        const char* next1 = first1;
        while (result < len2 && next1 != last1) {
            while (next1 != last1) {
                if (st == 0) {
                    if (*next1 < 1 || *next1 > 3)
                        return static_cast<int>(result); // error.
                    st = *next1++;
                } else if (st == 1) {
                    ++result;
                    st = 0;
                    break;
                } else {
                    if (*next1++ != 0)
                        return static_cast<int>(result); // error.
                    --st;
                }
            }
        }
        return static_cast<int>(result);
    }
};

//------------------Definition of stateless_null_padded_codevt----------------//

class stateless_null_padded_codecvt
    : public std::codecvt<wchar_t, char, std::mbstate_t>
{
    std::codecvt_base::result
    do_in( state_type&, const char* first1, const char* last1,
           const char*& next1, wchar_t* first2, wchar_t* last2,
           wchar_t*& next2 ) const
    {
        using namespace std;
        for ( next1 = first1, next2 = first2;
              next1 != last1 && next2 != last2; )
        {
            int len = (unsigned char) *next1;
            if (len < 1 || len > 3)
                return codecvt_base::error;
            if (last1 - next1 < len + 1)
                return codecvt_base::partial;
            ++next1;
            while (len-- > 1)
                if (*next1++ != 0)
                    return codecvt_base::error;
            *next2++ = (unsigned char) *next1++;
        }
        return next1 == last1 && next2 == last2 ?
            codecvt_base::ok :
            codecvt_base::partial;
    }

    std::codecvt_base::result
    do_out( state_type&, const wchar_t* first1, const wchar_t* last1,
            const wchar_t*& next1, char* first2, char* last2,
            char*& next2 ) const
    {
        using namespace std;
        for ( next1 = first1, next2 = first2;
              next1 != last1 && next2 != last2; )
        {
            if (*next1 > integer_traits<unsigned char>::const_max)
                return codecvt_base::noconv;
            int skip = *next1 % 3 + 2;
            if (last2 - next2 < skip)
                return codecvt_base::partial;
            *next2++ = static_cast<char>(--skip);
            while (skip-- > 1)
                *next2++ = 0;
            *next2++ = (unsigned char) *next1++;
        }
        return codecvt_base::ok;
    }

    std::codecvt_base::result
    do_unshift( state_type&,
                char* /* first2 */,
                char* /* last2 */,
                char*& /* next2 */ ) const
    {
        return std::codecvt_base::ok;
    }

    bool do_always_noconv() const throw() { return false; }

    int do_max_length() const throw() { return 4; }

    int do_encoding() const throw() { return -1; }

    int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER state_type&,
                   const char* first1, const char* last1,
                   std::size_t len2 ) const throw()
    {   // Implementation should follow that of do_in().
        std::size_t result = 0;
        for ( const char* next1 = first1;
              next1 != last1 && result < len2; ++result)
        {
            int len = (unsigned char) *next1;
            if (len < 1 || len > 3 || last1 - next1 < len + 1)
                return static_cast<int>(result); // error.
            ++next1;
            while (len-- > 1)
                if (*next1++ != 0)
                    return static_cast<int>(result); // error.
            ++next1;
        }
        return static_cast<int>(result);
    }
};

} } } // End namespaces detail, iostreams, boost.

#endif // #ifndef BOOST_IOSTREAMS_TEST_NULL_PADDED_CODECVT_HPP_INCLUDED

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
/**
* \file random-matrix-example.cc
*
* \author Tobias Waurick
* \date 21.06.17
*
*
*/
#include "ns3/random-matrix.h"
#include "ns3/core-module.h"
#include <iostream>
#include <armadillo>
#include <stdint.h>

using namespace std;
using namespace arma;

int main(int argc, char *argv[])
{
	CommandLine cmd;
	uint32_t seed1 = 1,
			seed2 = 1;
	cmd.AddValue("seed1", "first seed", seed1);
	cmd.AddValue("seed2", "second", seed2);
	cmd.Parse(argc, argv);

	cout << "########### 10x20 RANDOM IDENTITY MATRIX ###########" << endl;
	IdentRandomMatrix ranMat(10, 20);
	Col<double> x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
	Row<double> y = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	mat test = ranMat;

	cout << "-Seed: " << seed1 << endl;
	ranMat.Generate(seed1);
	cout << ranMat;

	cout << "-Seed: " << seed2 << endl;
	ranMat.Generate(seed2);
	cout << ranMat;

	cout << "-Multiplication: Mat * [1 2 3 ... 20]T" << endl;
	cout << (ranMat * x);

	cout << "-Multiplication: [1 2 3 .. 10]*Mat" << endl;
	cout << (y * ranMat);

	cout << "Rescaling to 5x10" << endl;
	ranMat.SetSize(5, 10);
	cout << ranMat;
	cout << "########### 10x20 RANDOM GAUSSIAN MATRIX with mean 0 var 1###########" << endl;
	GaussianRandomMatrix ranMat2(0, 1, 10, 20);

		cout << "-Seed: " << seed1 << endl;
	ranMat2.Generate(seed1);
	cout << ranMat2;

	cout << "-Seed: " << seed2 << endl;
	ranMat2.Generate(seed2);
	cout << ranMat2;

	cout << "-Mean :" << endl;
	cout << mean(mean(mat(ranMat2))) << endl;
	cout << "-Variance :" << endl;
	test = mat(ranMat2);
	test.reshape(200, 1);
	cout << var(test) << endl;

	cout << "Normalized" << endl;
	ranMat2.NormalizeToM();
	cout << ranMat2;
	cout << "-Mean :" << endl;
	cout << mean(mean(mat(ranMat2))) << endl;
	cout << "-Variance :" << endl;
	test = mat(ranMat2);
	test.reshape(200, 1);
	cout << var(test) << endl;

	cout << "Rescaling to 5x10" << endl;
	ranMat2.SetSize(5, 10);
	cout << ranMat2;
	cout << "########### 10x20 RANDOM BERNOULLIMATRIX###########" << endl;
	BernRandomMatrix ranMat3(10, 20);
		cout << "-Seed: " << seed1 << endl;
	ranMat3.Generate(seed1);
	cout << ranMat3;

	cout << "-Seed: " << seed2 << endl;
	ranMat3.Generate(seed2);
	cout << ranMat3;

	cout << "Normalized" << endl;
	ranMat3.NormalizeToM();
	cout << ranMat3;

	cout << "-Mean :" << endl;
	cout << mean(mean(mat(ranMat3))) << endl;
}


text:
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, Indiana University,
// Bloomington, IN 47405.
//
// Permission to modify the code and to distribute the code is
// granted, provided the text of this NOTICE is retained, a notice if
// the code was modified is included with the above COPYRIGHT NOTICE
// and with the COPYRIGHT NOTICE in the LICENSE file, and that the
// LICENSE file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#include <boost/config.hpp>

#include <algorithm>
#include <vector>
#include <utility>
#include <iostream>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/graph_utility.hpp>

int
main()
{
  using namespace boost;
  typedef adjacency_list < vecS, vecS, bidirectionalS > Graph;

  Graph G(5);
  add_edge(0, 2, G);
  add_edge(1, 1, G);
  add_edge(1, 3, G);
  add_edge(1, 4, G);
  add_edge(2, 1, G);
  add_edge(2, 3, G);
  add_edge(2, 4, G);
  add_edge(3, 1, G);
  add_edge(3, 4, G);
  add_edge(4, 0, G);
  add_edge(4, 1, G);

  std::cout << "original graph:" << std::endl;
  print_graph(G, get(vertex_index, G));

  std::cout << std::endl << "reversed graph:" << std::endl;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300  // avoid VC++ bug...
  reverse_graph<Graph> R(G);
  print_graph(R, get(vertex_index, G));
#else
  print_graph(make_reverse_graph(G), get(vertex_index, G));
#endif

  return EXIT_SUCCESS;
}


text:
#include <iostream>
#include <boost/mpl/string.hpp>

template<int N>
struct Num {
	static const int value = N;
};

int main() {
	std::cerr << Num<0>::value << std::endl;
}

max_stars_repo_name: taku-xhift/labo

max_issues_repo_name: taku-xhift/labo

max_forks_repo_name: taku-xhift/labo


text:
//==================================================================================================
/**
  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
**/
//==================================================================================================
#include <boost/simd/range/segmented_range.hpp>
#include <boost/simd/function/enumerate.hpp>
#include <boost/simd/pack.hpp>
#include <simd_test.hpp>
#include <vector>

STF_CASE_TPL("perfect iteration", STF_NUMERIC_TYPES)
{
  using boost::simd::pack;
  using boost::simd::enumerate;
  using boost::simd::segmented_range;

  auto sz = pack<T>::static_size;
  std::vector<T>  data(sz*5);
  std::vector<T>  ref (sz*5);

  for(std::size_t i=0;i<ref.size();++i) ref[i] = i;
  auto pr = segmented_range(data);

  T k = 0;
  for( auto&& pe : pr.head ) pe = k++;
  for( auto&& me : pr.body ) { me = enumerate<pack<T>>(k); k+=sz; }
  for( auto&& ee : pr.tail ) ee = k++;

  STF_EQUAL( std::distance(boost::begin(pr.head),boost::end(pr.head)), 0);
  STF_EQUAL( std::distance(boost::begin(pr.body),boost::end(pr.body)), 5);
  STF_EQUAL( std::distance(boost::begin(pr.tail),boost::end(pr.tail)), 0);
  STF_ALL_EQUAL(ref, data);
}

STF_CASE_TPL("iteration with tail", STF_NUMERIC_TYPES)
{
  using boost::simd::pack;
  using boost::simd::enumerate;
  using boost::simd::segmented_range;

  auto sz = pack<T>::static_size;
  std::vector<T>  base(sz*5-1);
  std::vector<T>  ref(sz*5-1);

  for(std::size_t i=0;i<ref.size();++i) ref[i] = i;

  auto data = boost::make_iterator_range(base.begin(), base.end());
  auto pr   = segmented_range(data);

  T k = 0;
  for( auto&& pe : pr.head ) pe = k++;
  for( auto&& me : pr.body ) { me = enumerate<pack<T>>(k); k+=sz; }
  for( auto&& ee : pr.tail ) ee = k++;

  STF_EQUAL( std::distance(boost::begin(pr.head),boost::end(pr.head)), 0);
  STF_EQUAL( std::distance(boost::begin(pr.body),boost::end(pr.body)), 4);
  STF_EQUAL( std::distance(boost::begin(pr.tail),boost::end(pr.tail)), sz-1);

  STF_ALL_EQUAL(ref, data);
}

STF_CASE_TPL("iteration with tail only", STF_NUMERIC_TYPES)
{
  using boost::simd::pack;
  using boost::simd::enumerate;
  using boost::simd::segmented_range;

  auto sz = pack<T>::static_size;
  std::vector<T>  base(pack<T>::static_size-1);
  std::vector<T>  ref(pack<T>::static_size-1);

  for(std::size_t i=0;i<ref.size();++i) ref[i] = i;

  auto data = boost::make_iterator_range(base.begin(), base.end());
  auto pr   = segmented_range(data);

  T k = 0;
  for( auto&& pe : pr.head ) pe = k++;
  for( auto&& me : pr.body ) { me = enumerate<pack<T>>(k); k+=sz; }
  for( auto&& ee : pr.tail ) ee = k++;

  STF_EQUAL( std::distance(boost::begin(pr.head),boost::end(pr.head)), 0);
  STF_EQUAL( std::distance(boost::begin(pr.body),boost::end(pr.body)), 0);
  STF_EQUAL( std::distance(boost::begin(pr.tail),boost::end(pr.tail)), sz-1);

  STF_ALL_EQUAL(ref, data);
}