feat(newton): first newton solver implementation
This commit is contained in:
@@ -11,10 +11,7 @@ export namespace mean_field::normalization {
|
||||
struct NormalizationPrescriptionTag { };
|
||||
|
||||
template <typename Candidate>
|
||||
concept NormalizationPrescription =
|
||||
std::derived_from<
|
||||
std::remove_cvref_t<Candidate>,
|
||||
NormalizationPrescriptionTag>;
|
||||
concept NormalizationPrescription = std::derived_from<std::remove_cvref_t<Candidate>, NormalizationPrescriptionTag>;
|
||||
|
||||
enum class CoordinateKind { value, residual };
|
||||
|
||||
@@ -50,44 +47,36 @@ export namespace mean_field::normalization {
|
||||
* numerical value of that factor. The owner type prevents one policy from
|
||||
* silently presenting another policy's runtime map as its own plan.
|
||||
*/
|
||||
template <NormalizationPrescription Prescription>
|
||||
struct RuntimePreparedCoordinate final {
|
||||
template <NormalizationPrescription Prescription> struct RuntimePreparedCoordinate final {
|
||||
using PrescriptionType = std::remove_cvref_t<Prescription>;
|
||||
};
|
||||
|
||||
template <RieszTopology Topology, PhysicalScaleKind Scale> struct PhysicalRieszCoordinate final {
|
||||
static constexpr RieszTopology topology = Topology;
|
||||
static constexpr PhysicalScaleKind scale = Scale;
|
||||
static constexpr RieszTopology topology = Topology;
|
||||
static constexpr PhysicalScaleKind scale = Scale;
|
||||
};
|
||||
|
||||
struct UnsupportedPhysicalRieszCoordinate final { };
|
||||
|
||||
template <typename Block> struct PhysicalRieszBlockTraits {
|
||||
using Method = UnsupportedPhysicalRieszCoordinate;
|
||||
static constexpr bool registered = false;
|
||||
using Method = UnsupportedPhysicalRieszCoordinate;
|
||||
static constexpr bool registered = false;
|
||||
};
|
||||
|
||||
template <CoordinateKind Kind, typename BlockList, typename MethodType>
|
||||
struct CoordinateComponent final {
|
||||
template <CoordinateKind Kind, typename BlockList, typename MethodType> struct CoordinateComponent final {
|
||||
using Blocks = BlockList;
|
||||
using Method = MethodType;
|
||||
static constexpr CoordinateKind kind = Kind;
|
||||
|
||||
using ValueBlocks = std::conditional_t<
|
||||
Kind == CoordinateKind::value,
|
||||
BlockList,
|
||||
utils::blocks::type_list<>>;
|
||||
using ResidualBlocks = std::conditional_t<
|
||||
Kind == CoordinateKind::residual,
|
||||
BlockList,
|
||||
utils::blocks::type_list<>>;
|
||||
using ValueBlocks = std::conditional_t<Kind == CoordinateKind::value, BlockList, utils::blocks::type_list<>>;
|
||||
using ResidualBlocks =
|
||||
std::conditional_t<Kind == CoordinateKind::residual, BlockList, utils::blocks::type_list<>>;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename Candidate> struct IsTypeList : std::false_type { };
|
||||
|
||||
template <typename... Types>
|
||||
struct IsTypeList<utils::blocks::type_list<Types...>> : std::true_type { };
|
||||
template <typename... Types> struct IsTypeList<utils::blocks::type_list<Types...>> : std::true_type { };
|
||||
|
||||
template <typename List, typename Base> struct IsUniqueDerivedBlockList : std::false_type { };
|
||||
|
||||
@@ -102,8 +91,7 @@ export namespace mean_field::normalization {
|
||||
template <> struct IsCoordinateMethod<IdentityCoordinate> : std::true_type { };
|
||||
|
||||
template <NormalizationPrescription Prescription>
|
||||
struct IsCoordinateMethod<RuntimePreparedCoordinate<Prescription>>
|
||||
: std::true_type { };
|
||||
struct IsCoordinateMethod<RuntimePreparedCoordinate<Prescription>> : std::true_type { };
|
||||
|
||||
template <RieszTopology Topology, PhysicalScaleKind Scale>
|
||||
struct IsCoordinateMethod<PhysicalRieszCoordinate<Topology, Scale>> : std::true_type { };
|
||||
@@ -121,10 +109,9 @@ export namespace mean_field::normalization {
|
||||
template <RieszTopology Topology, PhysicalScaleKind Scale, typename Block>
|
||||
struct MethodSupportsBlock<PhysicalRieszCoordinate<Topology, Scale>, Block>
|
||||
: std::bool_constant<
|
||||
PhysicalRieszBlockTraits<Block>::registered &&
|
||||
std::same_as<
|
||||
typename PhysicalRieszBlockTraits<Block>::Method,
|
||||
PhysicalRieszCoordinate<Topology, Scale>>> { };
|
||||
PhysicalRieszBlockTraits<Block>::registered && std::same_as<
|
||||
typename PhysicalRieszBlockTraits<Block>::Method,
|
||||
PhysicalRieszCoordinate<Topology, Scale>>> { };
|
||||
|
||||
template <typename Method, typename List> struct MethodSupportsEveryBlock : std::false_type { };
|
||||
|
||||
@@ -166,8 +153,7 @@ export namespace mean_field::normalization {
|
||||
}();
|
||||
|
||||
static constexpr bool hasCoherentCoordinateLists = [] {
|
||||
if constexpr (!hasValidKind || !IsTypeList<ValueBlocks>::value ||
|
||||
!IsTypeList<ResidualBlocks>::value) {
|
||||
if constexpr (!hasValidKind || !IsTypeList<ValueBlocks>::value || !IsTypeList<ResidualBlocks>::value) {
|
||||
return false;
|
||||
} else if constexpr (Candidate::kind == CoordinateKind::value) {
|
||||
return std::same_as<ValueBlocks, Blocks> &&
|
||||
@@ -182,8 +168,7 @@ export namespace mean_field::normalization {
|
||||
|
||||
static constexpr bool valid = hasValidKind && IsTypeList<Blocks>::value &&
|
||||
IsCoordinateMethod<Method>::value && hasValidBlockList &&
|
||||
hasCoherentCoordinateLists &&
|
||||
MethodSupportsEveryBlock<Method, Blocks>::value;
|
||||
hasCoherentCoordinateLists && MethodSupportsEveryBlock<Method, Blocks>::value;
|
||||
};
|
||||
|
||||
template <typename... Lists> struct Concatenate;
|
||||
@@ -205,23 +190,18 @@ export namespace mean_field::normalization {
|
||||
|
||||
template <typename List, typename Type> struct Append;
|
||||
|
||||
template <typename... Types, typename Appended>
|
||||
struct Append<utils::blocks::type_list<Types...>, Appended> {
|
||||
template <typename... Types, typename Appended> struct Append<utils::blocks::type_list<Types...>, Appended> {
|
||||
using Type = utils::blocks::type_list<Types..., Appended>;
|
||||
};
|
||||
|
||||
template <typename List, typename Type> using AppendT = typename Append<List, Type>::Type;
|
||||
|
||||
template <typename List, typename Type>
|
||||
using AppendUniqueT = std::conditional_t<
|
||||
utils::blocks::contains_type_v<Type, List>,
|
||||
List,
|
||||
AppendT<List, Type>>;
|
||||
using AppendUniqueT = std::conditional_t<utils::blocks::contains_type_v<Type, List>, List, AppendT<List, Type>>;
|
||||
|
||||
template <typename Source, typename Excluded> struct ListDifference;
|
||||
|
||||
template <typename Excluded>
|
||||
struct ListDifference<utils::blocks::type_list<>, Excluded> {
|
||||
template <typename Excluded> struct ListDifference<utils::blocks::type_list<>, Excluded> {
|
||||
using Type = utils::blocks::type_list<>;
|
||||
};
|
||||
|
||||
@@ -260,10 +240,7 @@ export namespace mean_field::normalization {
|
||||
};
|
||||
|
||||
template <typename List>
|
||||
using RepeatedTypesT = typename CollectRepeatedTypes<
|
||||
List,
|
||||
List,
|
||||
utils::blocks::type_list<>>::Type;
|
||||
using RepeatedTypesT = typename CollectRepeatedTypes<List, List, utils::blocks::type_list<>>::Type;
|
||||
|
||||
template <typename Candidate, typename = void> struct PlanTraits {
|
||||
static constexpr bool valid = false;
|
||||
@@ -274,23 +251,20 @@ export namespace mean_field::normalization {
|
||||
concept NormalizationComponent = detail::ComponentTraits<std::remove_cvref_t<Candidate>>::valid;
|
||||
|
||||
template <typename... Components> struct NormalizationPlan final {
|
||||
using ComponentTypes = utils::blocks::type_list<Components...>;
|
||||
using ValueBlocks = detail::ConcatenateT<typename Components::ValueBlocks...>;
|
||||
using ResidualBlocks = detail::ConcatenateT<typename Components::ResidualBlocks...>;
|
||||
using ComponentTypes = utils::blocks::type_list<Components...>;
|
||||
using ValueBlocks = detail::ConcatenateT<typename Components::ValueBlocks...>;
|
||||
using ResidualBlocks = detail::ConcatenateT<typename Components::ResidualBlocks...>;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename... Components>
|
||||
struct PlanTraits<NormalizationPlan<Components...>> {
|
||||
template <typename... Components> struct PlanTraits<NormalizationPlan<Components...>> {
|
||||
static constexpr bool valid = (ComponentTraits<Components>::valid && ...);
|
||||
};
|
||||
|
||||
template <typename Values, typename Residuals> struct MakeIdentityPlan;
|
||||
|
||||
template <typename... Values, typename... Residuals>
|
||||
struct MakeIdentityPlan<
|
||||
utils::blocks::type_list<Values...>,
|
||||
utils::blocks::type_list<Residuals...>> {
|
||||
struct MakeIdentityPlan<utils::blocks::type_list<Values...>, utils::blocks::type_list<Residuals...>> {
|
||||
using Type = NormalizationPlan<
|
||||
CoordinateComponent<CoordinateKind::value, utils::blocks::type_list<Values>, IdentityCoordinate>...,
|
||||
CoordinateComponent<
|
||||
@@ -299,30 +273,18 @@ export namespace mean_field::normalization {
|
||||
IdentityCoordinate>...>;
|
||||
};
|
||||
|
||||
template <
|
||||
NormalizationPrescription Prescription,
|
||||
typename Values,
|
||||
typename Residuals>
|
||||
template <NormalizationPrescription Prescription, typename Values, typename Residuals>
|
||||
struct MakeRuntimePreparedPlan;
|
||||
|
||||
template <
|
||||
NormalizationPrescription Prescription,
|
||||
typename... Values,
|
||||
typename... Residuals>
|
||||
template <NormalizationPrescription Prescription, typename... Values, typename... Residuals>
|
||||
struct MakeRuntimePreparedPlan<
|
||||
Prescription,
|
||||
utils::blocks::type_list<Values...>,
|
||||
utils::blocks::type_list<Residuals...>> {
|
||||
using Method = RuntimePreparedCoordinate<Prescription>;
|
||||
using Type = NormalizationPlan<
|
||||
CoordinateComponent<
|
||||
CoordinateKind::value,
|
||||
utils::blocks::type_list<Values>,
|
||||
Method>...,
|
||||
CoordinateComponent<
|
||||
CoordinateKind::residual,
|
||||
utils::blocks::type_list<Residuals>,
|
||||
Method>...>;
|
||||
using Type = NormalizationPlan<
|
||||
CoordinateComponent<CoordinateKind::value, utils::blocks::type_list<Values>, Method>...,
|
||||
CoordinateComponent<CoordinateKind::residual, utils::blocks::type_list<Residuals>, Method>...>;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
@@ -331,46 +293,43 @@ export namespace mean_field::normalization {
|
||||
|
||||
template <typename Form>
|
||||
requires utils::blocks::block_form_is_valid_v<Form>
|
||||
using IdentityNormalizationPlanFor = typename detail::MakeIdentityPlan<
|
||||
typename Form::value_blocks,
|
||||
typename Form::residual_blocks>::Type;
|
||||
using IdentityNormalizationPlanFor =
|
||||
typename detail::MakeIdentityPlan<typename Form::value_blocks, typename Form::residual_blocks>::Type;
|
||||
|
||||
template <NormalizationPrescription Prescription, typename Form>
|
||||
requires utils::blocks::block_form_is_valid_v<Form>
|
||||
using RuntimePreparedNormalizationPlanFor =
|
||||
typename detail::MakeRuntimePreparedPlan<
|
||||
std::remove_cvref_t<Prescription>,
|
||||
typename Form::value_blocks,
|
||||
typename Form::residual_blocks>::Type;
|
||||
using RuntimePreparedNormalizationPlanFor = typename detail::MakeRuntimePreparedPlan<
|
||||
std::remove_cvref_t<Prescription>,
|
||||
typename Form::value_blocks,
|
||||
typename Form::residual_blocks>::Type;
|
||||
|
||||
template <typename Form, typename Plan>
|
||||
requires utils::blocks::block_form_is_valid_v<Form>
|
||||
struct NormalizationCoverage final {
|
||||
using DeclaredValueBlocks = typename Plan::ValueBlocks;
|
||||
using DeclaredValueBlocks = typename Plan::ValueBlocks;
|
||||
using DeclaredResidualBlocks = typename Plan::ResidualBlocks;
|
||||
|
||||
using MissingValueBlocks = detail::ListDifferenceT<typename Form::value_blocks, DeclaredValueBlocks>;
|
||||
using UnexpectedValueBlocks = detail::ListDifferenceT<DeclaredValueBlocks, typename Form::value_blocks>;
|
||||
using RepeatedValueBlocks = detail::RepeatedTypesT<DeclaredValueBlocks>;
|
||||
using MissingValueBlocks = detail::ListDifferenceT<typename Form::value_blocks, DeclaredValueBlocks>;
|
||||
using UnexpectedValueBlocks = detail::ListDifferenceT<DeclaredValueBlocks, typename Form::value_blocks>;
|
||||
using RepeatedValueBlocks = detail::RepeatedTypesT<DeclaredValueBlocks>;
|
||||
|
||||
using MissingResidualBlocks = detail::ListDifferenceT<typename Form::residual_blocks, DeclaredResidualBlocks>;
|
||||
using UnexpectedResidualBlocks = detail::ListDifferenceT<DeclaredResidualBlocks, typename Form::residual_blocks>;
|
||||
using RepeatedResidualBlocks = detail::RepeatedTypesT<DeclaredResidualBlocks>;
|
||||
using MissingResidualBlocks = detail::ListDifferenceT<typename Form::residual_blocks, DeclaredResidualBlocks>;
|
||||
using UnexpectedResidualBlocks =
|
||||
detail::ListDifferenceT<DeclaredResidualBlocks, typename Form::residual_blocks>;
|
||||
using RepeatedResidualBlocks = detail::RepeatedTypesT<DeclaredResidualBlocks>;
|
||||
|
||||
static constexpr bool hasEveryValueBlock = MissingValueBlocks::size == 0;
|
||||
static constexpr bool hasOnlyValueBlocks = UnexpectedValueBlocks::size == 0;
|
||||
static constexpr bool hasUniqueValueOwners = RepeatedValueBlocks::size == 0;
|
||||
static constexpr bool hasEveryResidualBlock = MissingResidualBlocks::size == 0;
|
||||
static constexpr bool hasOnlyResidualBlocks = UnexpectedResidualBlocks::size == 0;
|
||||
static constexpr bool hasEveryValueBlock = MissingValueBlocks::size == 0;
|
||||
static constexpr bool hasOnlyValueBlocks = UnexpectedValueBlocks::size == 0;
|
||||
static constexpr bool hasUniqueValueOwners = RepeatedValueBlocks::size == 0;
|
||||
static constexpr bool hasEveryResidualBlock = MissingResidualBlocks::size == 0;
|
||||
static constexpr bool hasOnlyResidualBlocks = UnexpectedResidualBlocks::size == 0;
|
||||
static constexpr bool hasUniqueResidualOwners = RepeatedResidualBlocks::size == 0;
|
||||
|
||||
static constexpr bool complete = hasEveryValueBlock && hasOnlyValueBlocks && hasUniqueValueOwners &&
|
||||
hasEveryResidualBlock && hasOnlyResidualBlocks &&
|
||||
hasUniqueResidualOwners;
|
||||
hasEveryResidualBlock && hasOnlyResidualBlocks && hasUniqueResidualOwners;
|
||||
};
|
||||
|
||||
template <typename Plan, typename Form>
|
||||
concept CompleteNormalizationFor = utils::blocks::block_form_is_valid_v<Form> &&
|
||||
NormalizationPlanType<Plan> &&
|
||||
concept CompleteNormalizationFor = utils::blocks::block_form_is_valid_v<Form> && NormalizationPlanType<Plan> &&
|
||||
NormalizationCoverage<Form, std::remove_cvref_t<Plan>>::complete;
|
||||
} // namespace mean_field::normalization
|
||||
|
||||
Reference in New Issue
Block a user