You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
7.0 KiB
196 lines
7.0 KiB
// Ceres Solver - A fast non-linear least squares minimizer
|
|
// Copyright 2023 Google Inc. All rights reserved.
|
|
// http://ceres-solver.org/
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
// * Neither the name of Google Inc. nor the names of its contributors may be
|
|
// used to endorse or promote products derived from this software without
|
|
// specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Author: sergiu.deitsch@gmail.com (Sergiu Deitsch)
|
|
//
|
|
|
|
#ifndef CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
|
|
#define CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
|
|
|
|
#include <tuple>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
#include "ceres/internal/integer_sequence_algorithm.h"
|
|
#include "ceres/jet_fwd.h"
|
|
|
|
namespace ceres {
|
|
namespace internal {
|
|
|
|
// Predicate that determines whether any of the Types is a Jet.
|
|
template <typename... Types>
|
|
struct AreAnyJet : std::false_type {};
|
|
|
|
template <typename T, typename... Types>
|
|
struct AreAnyJet<T, Types...> : AreAnyJet<Types...> {};
|
|
|
|
template <typename T, int N, typename... Types>
|
|
struct AreAnyJet<Jet<T, N>, Types...> : std::true_type {};
|
|
|
|
// Convenience variable template for AreAnyJet.
|
|
template <typename... Types>
|
|
inline constexpr bool AreAnyJet_v = AreAnyJet<Types...>::value;
|
|
|
|
// Extracts the underlying floating-point from a type T.
|
|
template <typename T, typename E = void>
|
|
struct UnderlyingScalar {
|
|
using type = T;
|
|
};
|
|
|
|
template <typename T, int N>
|
|
struct UnderlyingScalar<Jet<T, N>> : UnderlyingScalar<T> {};
|
|
|
|
// Convenience template alias for UnderlyingScalar type trait.
|
|
template <typename T>
|
|
using UnderlyingScalar_t = typename UnderlyingScalar<T>::type;
|
|
|
|
// Predicate determining whether all Types in the pack are the same.
|
|
//
|
|
// Specifically, the predicate applies std::is_same recursively to pairs of
|
|
// Types in the pack.
|
|
template <typename T1, typename... Types>
|
|
inline constexpr bool AreAllSame_v = (std::is_same<T1, Types>::value && ...);
|
|
|
|
// Determines the rank of a type. This allows to ensure that types passed as
|
|
// arguments are compatible to each other. The rank of Jet is determined by the
|
|
// dimensions of the dual part. The rank of a scalar is always 0.
|
|
// Non-specialized types default to a rank of -1.
|
|
template <typename T, typename E = void>
|
|
struct Rank : std::integral_constant<int, -1> {};
|
|
|
|
// The rank of a scalar is 0.
|
|
template <typename T>
|
|
struct Rank<T, std::enable_if_t<std::is_scalar<T>::value>>
|
|
: std::integral_constant<int, 0> {};
|
|
|
|
// The rank of a Jet is given by its dimensionality.
|
|
template <typename T, int N>
|
|
struct Rank<Jet<T, N>> : std::integral_constant<int, N> {};
|
|
|
|
// Convenience variable template for Rank.
|
|
template <typename T>
|
|
inline constexpr int Rank_v = Rank<T>::value;
|
|
|
|
// Constructs an integer sequence of ranks for each of the Types in the pack.
|
|
template <typename... Types>
|
|
using Ranks_t = std::integer_sequence<int, Rank_v<Types>...>;
|
|
|
|
// Returns the scalar part of a type. This overload acts as an identity.
|
|
template <typename T>
|
|
constexpr decltype(auto) AsScalar(T&& value) noexcept {
|
|
return std::forward<T>(value);
|
|
}
|
|
|
|
// Recursively unwraps the scalar part of a Jet until a non-Jet scalar type is
|
|
// encountered.
|
|
template <typename T, int N>
|
|
constexpr decltype(auto) AsScalar(const Jet<T, N>& value) noexcept(
|
|
noexcept(AsScalar(value.a))) {
|
|
return AsScalar(value.a);
|
|
}
|
|
|
|
} // namespace internal
|
|
|
|
// Type trait ensuring at least one of the types is a Jet,
|
|
// the underlying scalar types are the same and Jet dimensions match.
|
|
//
|
|
// The type trait can be further specialized if necessary.
|
|
//
|
|
// This trait is a candidate for a concept definition once C++20 features can
|
|
// be used.
|
|
template <typename... Types>
|
|
// clang-format off
|
|
struct CompatibleJetOperands : std::integral_constant
|
|
<
|
|
bool,
|
|
// At least one of the types is a Jet
|
|
internal::AreAnyJet_v<Types...> &&
|
|
// The underlying floating-point types are exactly the same
|
|
internal::AreAllSame_v<internal::UnderlyingScalar_t<Types>...> &&
|
|
// Non-zero ranks of types are equal
|
|
internal::IsEmptyOrAreAllEqual_v<internal::RemoveValue_t<internal::Ranks_t<Types...>, 0>>
|
|
>
|
|
// clang-format on
|
|
{};
|
|
|
|
// Single Jet operand is always compatible.
|
|
template <typename T, int N>
|
|
struct CompatibleJetOperands<Jet<T, N>> : std::true_type {};
|
|
|
|
// Single non-Jet operand is always incompatible.
|
|
template <typename T>
|
|
struct CompatibleJetOperands<T> : std::false_type {};
|
|
|
|
// Empty operands are always incompatible.
|
|
template <>
|
|
struct CompatibleJetOperands<> : std::false_type {};
|
|
|
|
// Convenience variable template ensuring at least one of the types is a Jet,
|
|
// the underlying scalar types are the same and Jet dimensions match.
|
|
//
|
|
// This trait is a candidate for a concept definition once C++20 features can
|
|
// be used.
|
|
template <typename... Types>
|
|
inline constexpr bool CompatibleJetOperands_v =
|
|
CompatibleJetOperands<Types...>::value;
|
|
|
|
// Type trait ensuring at least one of the types is a Jet,
|
|
// the underlying scalar types are compatible among each other and Jet
|
|
// dimensions match.
|
|
//
|
|
// The type trait can be further specialized if necessary.
|
|
//
|
|
// This trait is a candidate for a concept definition once C++20 features can
|
|
// be used.
|
|
template <typename... Types>
|
|
// clang-format off
|
|
struct PromotableJetOperands : std::integral_constant
|
|
<
|
|
bool,
|
|
// Types can be compatible among each other
|
|
internal::AreAnyJet_v<Types...> &&
|
|
// Non-zero ranks of types are equal
|
|
internal::IsEmptyOrAreAllEqual_v<internal::RemoveValue_t<internal::Ranks_t<Types...>, 0>>
|
|
>
|
|
// clang-format on
|
|
{};
|
|
|
|
// Convenience variable template ensuring at least one of the types is a Jet,
|
|
// the underlying scalar types are compatible among each other and Jet
|
|
// dimensions match.
|
|
//
|
|
// This trait is a candidate for a concept definition once C++20 features can
|
|
// be used.
|
|
template <typename... Types>
|
|
inline constexpr bool PromotableJetOperands_v =
|
|
PromotableJetOperands<Types...>::value;
|
|
|
|
} // namespace ceres
|
|
|
|
#endif // CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
|