Program Listing for File inspect.hpp
↰ Return to documentation for file (src/navtk/inspect.hpp)
#pragma once
#include <initializer_list>
#include <navtk/tensors.hpp>
#include <type_traits>
#include <xtensor/utils/xutils.hpp>
namespace navtk {
template <typename T>
bool has_zero_size(const T& expression) {
return expression.begin() == expression.end();
}
bool is_symmetric(const Matrix& mat, double rtol = 1e-5, double atol = 1e-8);
bool is_diagonal(const Matrix& mat);
bool is_identity(const Matrix& mat);
std::vector<std::pair<Size, Size>> non_symmetric_elements(const Matrix& mat,
double rtol = 1e-5,
double atol = 1e-8);
template <typename T>
struct InitializerListDepth {
using type = T;
static constexpr size_t value = 0;
};
template <typename T>
struct InitializerListDepth<std::initializer_list<T>> {
using type = typename InitializerListDepth<T>::type;
static constexpr size_t value = 1 + InitializerListDepth<T>::value;
};
// don't document initializer helper stuff, but only the final result.
#ifndef NEED_DOXYGEN_EXHALE_WORKAROUND
template <size_t D, typename C>
struct InitializerListNested {
using type =
std::initializer_list<typename InitializerListNested<(D > 1) ? D - 1 : 1, C>::type>;
};
// Base case of 1 dimesional
template <typename C>
struct InitializerListNested<1, C> {
using type = std::initializer_list<C>;
};
// Handle 0 dimensional case so tha compiler doesn't explode, but not intended for use.
template <typename C>
struct InitializerListNested<0, C> {
using type = C;
};
#endif
template <size_t D, typename C>
using Initializer = typename InitializerListNested<D, C>::type;
template <typename T, class = void>
struct TensorMeta {
static constexpr bool FIXED_DIMS = false;
};
template <typename T>
struct TensorMeta<T, std::enable_if_t<xt::is_xexpression<T>::value>> {
static constexpr bool FIXED_DIMS = true;
static constexpr auto DIM_COUNT =
std::tuple_size<typename std::remove_reference<T>::type::shape_type>::value;
};
template <typename T>
struct TensorMeta<T, std::enable_if_t<std::is_arithmetic<std::remove_reference_t<T>>::value>> {
static constexpr bool FIXED_DIMS = true;
static constexpr size_t DIM_COUNT = 0;
};
template <typename T>
struct TensorMeta<
T,
std::enable_if_t<InitializerListDepth<T>::value != 0 &&
std::is_arithmetic<typename InitializerListDepth<T>::type>::value>> {
static constexpr bool FIXED_DIMS = true;
static constexpr size_t DIM_COUNT = InitializerListDepth<T>::value;
};
template <typename T>
inline constexpr bool IS_VALID = (TensorMeta<T>::FIXED_DIMS);
template <size_t Dim, typename... T>
inline constexpr bool TENSORS_ARE_DIM =
((IS_VALID<T> && requires { typename std::enable_if_t<TensorMeta<T>::DIM_COUNT == Dim>; }) &&
...);
template <size_t Dim, typename... T>
inline constexpr bool TENSORS_ARE_LESS_THAN_DIM =
((IS_VALID<T> && requires { typename std::enable_if_t<(TensorMeta<T>::DIM_COUNT < Dim)>; }) &&
...);
template <size_t Dim, typename... T>
inline constexpr bool TENSORS_HAVE_MAX_DIM =
TENSORS_ARE_LESS_THAN_DIM<Dim + 1, T...> && !TENSORS_ARE_LESS_THAN_DIM<Dim, T...>;
template <bool Condition>
using IfCondition = std::enable_if_t<Condition>;
template <bool... Condition>
using IfAllConditions = IfCondition<(Condition && ...)>;
template <bool... Condition>
using IfAnyConditions = IfCondition<(Condition || ...)>;
template <typename T, std::size_t Dim>
using IfTensorOfDim = IfCondition<TENSORS_ARE_DIM<Dim, T>>;
template <typename A, typename B, std::size_t Dim>
using IfBothTensorsOfDim = IfCondition<TENSORS_ARE_DIM<Dim, A, B>>;
template <typename A, typename B, std::size_t Dim>
using IfFirstTensorOfDim = IfAllConditions<TENSORS_ARE_DIM<Dim, A>, !TENSORS_ARE_DIM<Dim, B>>;
template <typename A, typename B, std::size_t Dim>
using IfSecondTensorOfDim = IfAllConditions<TENSORS_ARE_DIM<Dim, B>, !TENSORS_ARE_DIM<Dim, A>>;
template <std::size_t Dim, typename... T>
using IfAnyTensorOfDim = IfAnyConditions<TENSORS_ARE_DIM<Dim, T>...>;
template <std::size_t Dim, typename... T>
using IfAllTensorsOfDim = IfCondition<TENSORS_ARE_DIM<Dim, T...>>;
template <std::size_t Dim, typename... T>
using IfNoTensorsOfDim = IfAllConditions<!TENSORS_ARE_DIM<Dim, T>...>;
template <std::size_t Dim, typename... T>
using IfTensorsMaxDim = IfAllConditions<TENSORS_ARE_LESS_THAN_DIM<Dim + 1, T...>,
!TENSORS_ARE_LESS_THAN_DIM<Dim, T...>>;
template <typename T>
using IfEigenInterface =
IfAllConditions<std::is_member_function_pointer<decltype(&T::rows)>::value,
std::is_member_function_pointer<decltype(&T::cols)>::value>;
Size num_rows(const Matrix& m);
Size num_rows(const Vector& c);
Size num_cols(const Matrix& m);
Size num_cols(const Vector& r);
} // namespace navtk