Skip to content

Commit

Permalink
construct blade_ordering from dimension mask
Browse files Browse the repository at this point in the history
Replace `type_identity` constructors. Add dimensions mask a static
member to `blade`.

Change-Id: Ib56ab207963942c9c542449ce984d1f00062f19f
  • Loading branch information
oliverlee committed Sep 29, 2024
1 parent 663d8c7 commit ed837d1
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 45 deletions.
21 changes: 12 additions & 9 deletions rigid_geometric_algebra/blade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
#include "rigid_geometric_algebra/detail/derive_subtraction.hpp"
#include "rigid_geometric_algebra/detail/derive_vector_space_operations.hpp"
#include "rigid_geometric_algebra/detail/even.hpp"
#include "rigid_geometric_algebra/detail/indices_array.hpp"
#include "rigid_geometric_algebra/detail/size_checked_subrange.hpp"
#include "rigid_geometric_algebra/detail/structural_bitset.hpp"
#include "rigid_geometric_algebra/detail/swaps_to_sorted_dimensions.hpp"
#include "rigid_geometric_algebra/glz_fwd.hpp"
#include "rigid_geometric_algebra/zero_constant.hpp"

#include <algorithm>
#include <array>
#include <concepts>
#include <cstddef>
Expand Down Expand Up @@ -74,13 +75,6 @@ class blade
detail::get_coefficient>,
detail::derive_subtraction<blade<A, Is...>>
{
// TODO replace
static constexpr auto sorted_dimensions = [] {
auto dims = std::array<std::size_t, sizeof...(Is)>{Is...};
std::ranges::sort(dims);
return dims;
}();

public:
/// algebra this blade belongs to
///
Expand All @@ -91,6 +85,15 @@ class blade
static constexpr auto grade =
std::integral_constant<std::size_t, sizeof...(Is)>{};

/// bitset type specifying the dimension mask
///
using dimension_mask_type = detail::structural_bitset<algebra_dimension_v<A>>;

/// factors that are present in this blade
///
static constexpr auto dimension_mask =
(dimension_mask_type{}.set(Is) | ... | dimension_mask_type{});

/// blade scalar type
///
using value_type = algebra_field_t<A>;
Expand All @@ -99,7 +102,7 @@ class blade
///
using canonical_type =
decltype([]<std::size_t... Js>(std::index_sequence<Js...>)
-> blade<A, sorted_dimensions[Js]...> {
-> blade<A, detail::indices_array<dimension_mask>[Js]...> {
return {};
}(std::make_index_sequence<sizeof...(Is)>{}));

Expand Down
27 changes: 5 additions & 22 deletions rigid_geometric_algebra/blade_ordering.hpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
#pragma once

#include "rigid_geometric_algebra/algebra_dimension.hpp"
#include "rigid_geometric_algebra/algebra_type.hpp"
#include "rigid_geometric_algebra/blade.hpp"
#include "rigid_geometric_algebra/detail/structural_bitset.hpp"
#include "rigid_geometric_algebra/is_algebra.hpp"
#include "rigid_geometric_algebra/is_blade.hpp"

#include <compare>
#include <cstddef>
#include <type_traits>

namespace rigid_geometric_algebra {

Expand All @@ -26,18 +21,13 @@ struct blade_ordering
///
mask_type mask{};

/// construct a `blade_ordering` from a blade type
/// construct with empty mask
///
template <std::size_t... Is>
constexpr blade_ordering(std::type_identity<blade<A, Is...>>) noexcept
: mask{(mask_type{}.set(Is) | ... | mask_type{})}
{}
blade_ordering() = default;

template <detail::blade B>
requires has_common_algebra_type_v<B, blade_ordering>
constexpr blade_ordering(std::type_identity<B>) noexcept
: blade_ordering(std::type_identity<std::remove_cvref_t<B>>{})
{}
/// construct from mask
///
constexpr blade_ordering(mask_type mask) : mask{mask} {}

/// equality operator
///
Expand All @@ -64,11 +54,4 @@ struct blade_ordering
}
};

template <class A>
requires is_algebra_v<A>
blade_ordering(std::type_identity<A>) -> blade_ordering<A>;

template <detail::blade B>
blade_ordering(std::type_identity<B>) -> blade_ordering<algebra_type_t<B>>;

} // namespace rigid_geometric_algebra
4 changes: 2 additions & 2 deletions rigid_geometric_algebra/is_canonical_blade_order.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class is_canonical_blade_order_fn
(std::is_same_v<Bs, canonical_type_t<Bs>> and ...) and
has_common_algebra_type_v<Bs...>) {
using A = common_algebra_type_t<Bs...>;
const auto data = std::array<blade_ordering<A>, sizeof...(Bs)>{
std::type_identity<Bs>{}...};
const auto data =
std::array<blade_ordering<A>, sizeof...(Bs)>{Bs::dimension_mask...};
return std::ranges::is_sorted(data, std::ranges::less_equal{});
}

Expand Down
4 changes: 2 additions & 2 deletions rigid_geometric_algebra/multivector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ constexpr auto operator+(B1&& b1, B2&& b2) -> sorted_canonical_blades_t<
canonical_type_t<B2>>::template insert_into_t<multivector<A>>
{
if constexpr (
blade_ordering{std::type_identity<B1>{}} <
blade_ordering{std::type_identity<B2>{}}) {
blade_ordering<A>{std::remove_cvref_t<B1>::dimension_mask} <
blade_ordering<A>{std::remove_cvref_t<B2>::dimension_mask}) {
return {std::forward<B1>(b1).canonical(), std::forward<B2>(b2).canonical()};
} else {
return {std::forward<B2>(b2).canonical(), std::forward<B1>(b1).canonical()};
Expand Down
2 changes: 1 addition & 1 deletion rigid_geometric_algebra/sorted_canonical_blades.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct sorted_canonical_blades
using A = common_algebra_type_t<Bs...>;

static constexpr auto sorted = [] {
auto values = std::array{blade_ordering{std::type_identity<Bs>{}}...};
auto values = std::array{blade_ordering<A>{Bs::dimension_mask}...};
std::ranges::sort(values);
const auto duplicates = std::ranges::unique(values);
return detail::array_subset(values, values.size() - duplicates.size());
Expand Down
5 changes: 2 additions & 3 deletions test/blade_ordering_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
#include "skytest/skytest.hpp"

#include <cstddef>
#include <type_traits>

using rga = ::rigid_geometric_algebra::algebra<double, 2>;
using G2 = ::rigid_geometric_algebra::algebra<double, 2>;
using ::rigid_geometric_algebra::blade_ordering;

template <std::size_t... Is>
constexpr auto ord = blade_ordering{std::type_identity<rga::blade<Is...>>{}};
constexpr auto ord = blade_ordering<G2>{G2::blade<Is...>::dimension_mask};

auto main() -> int
{
Expand Down
7 changes: 1 addition & 6 deletions test/blade_type_from_test.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include "rigid_geometric_algebra/rigid_geometric_algebra.hpp"
#include "skytest/skytest.hpp"

#include <type_traits>

template <class Out, class In>
struct impl
{
Expand All @@ -12,10 +10,7 @@ struct impl
using ::rigid_geometric_algebra::blade_ordering;
using ::rigid_geometric_algebra::blade_type_from_t;

return Out{} ==
blade_type_from_t<
algebra_type_t<In>,
blade_ordering{std::type_identity<In>{}}.mask>{};
return Out{} == blade_type_from_t<algebra_type_t<In>, In::dimension_mask>{};
}
};

Expand Down

0 comments on commit ed837d1

Please sign in to comment.