Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions core/include/detray/algebra/concepts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/** Algebra plugins library, part of the ACTS project
*
* (c) 2024 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

#pragma once

// Project include(s)
#include "detray/algebra/type_traits.hpp"

// System include(s).
#include <concepts>

namespace detray::concepts {

/// Arithmetic types
template <typename T>
concept arithmetic = std::is_arithmetic_v<T>;

/// Arithmetic types
template <typename T>
concept enumeration = std::is_enum_v<T>;

// Value concept: Single entry
template <typename T>
concept value = detray::concepts::arithmetic<std::decay_t<T>>;

// Element concept: Single entry, not necessarily for vector/matrix operations
template <typename T>
concept element = detray::concepts::value<T> ||
detray::concepts::enumeration<std::decay_t<T>>;

/// Scalar concept: Elements of vectors/matrices (can be simd vectors)
template <typename T>
concept scalar = !algebra::traits::is_matrix<T> &&
!algebra::traits::is_vector<T> && requires(T a, T b) {
{ a + b }
->std::convertible_to<T>;
{ a - b }
->std::convertible_to<T>;
{ a* b }
->std::convertible_to<T>;
{ a / b }
->std::convertible_to<T>;
};

/// Check if a scalar is simd
template <typename T>
concept simd_scalar = scalar<T> && !std::is_scalar_v<T>;

/// Index concept to access vector/matrix elements
template <typename T>
concept index = std::is_integral_v<T> && !std::same_as<T, bool>;

/// Vector concepts
/// @{
template <typename V>
concept vector = algebra::traits::is_vector<V>;

template <typename V>
concept vector2D = vector<V> && (algebra::traits::size<V> == 2);

template <typename V>
concept vector3D = vector<V> && (algebra::traits::size<V> == 3);
/// @}

/// Point concepts
/// @{
template <typename V>
concept point = vector<V>;

template <typename V>
concept point2D = point<V> && (algebra::traits::size<V> == 2);

template <typename V>
concept point3D = point<V> && (algebra::traits::size<V> == 3);
/// @}

/// Matrix concepts
/// @{
template <typename M>
concept matrix = algebra::traits::is_matrix<M>;

template <typename M>
concept square_matrix = matrix<M>&& algebra::traits::is_square<M>;

template <typename M>
concept row_matrix = matrix<M> && (algebra::traits::rows<M> == 1);

template <typename M>
concept row_matrix3D = row_matrix<M> && (algebra::traits::rows<M> == 3);

template <typename M>
concept column_matrix = matrix<M> && (algebra::traits::columns<M> == 1);

template <typename M>
concept column_matrix3D = column_matrix<M> && (algebra::traits::rows<M> == 3);

template <typename MA, typename MB>
concept matrix_compatible = matrix<MA>&& matrix<MB>&& std::convertible_to<
algebra::traits::index_t<MA>, algebra::traits::index_t<MB>>&&
std::convertible_to<algebra::traits::index_t<MB>,
algebra::traits::index_t<MA>>;

template <typename MA, typename MB>
concept matrix_multipliable =
matrix_compatible<MA, MB> &&
(algebra::traits::columns<MA> ==
algebra::traits::rows<MB>)&&requires(algebra::traits::scalar_t<MA> sa,
algebra::traits::scalar_t<MB> sb) {
{(sa * sb) + (sa * sb)};
};

template <typename MA, typename MB, typename MC>
concept matrix_multipliable_into =
matrix_multipliable<MA, MB>&& matrix_compatible<MA, MC>&&
matrix_compatible<MB, MC> &&
(algebra::traits::rows<MC> == algebra::traits::rows<MA>)&&(
algebra::traits::columns<MC> ==
algebra::traits::columns<
MB>)&&requires(algebra::traits::scalar_t<MA> sa,
algebra::traits::scalar_t<MB> sb,
algebra::traits::scalar_t<MC>& sc) {
{sc += (sa * sb)};
};
/// @}

/// Transform concept
template <typename T>
concept transform3D = requires(T trf) {
// Local type definitions
requires scalar<typename T::scalar_type>;
requires vector3D<typename T::vector3>;
requires point2D<typename T::point2>;
requires point3D<typename T::point3>;

// Methods
trf.rotation();
trf.translation();
trf.point_to_global(typename T::vector3());
trf.point_to_local(typename T::vector3());
trf.vector_to_global(typename T::vector3());
trf.vector_to_local(typename T::vector3());
};

/// Algebra plugin concept
template <typename A>
concept algebra = (concepts::value<typename A::value_type> &&
concepts::scalar<typename A::scalar> &&
concepts::index<typename A::size_type> &&
concepts::vector3D<typename A::vector3D> &&
concepts::point2D<typename A::point2D> &&
concepts::point3D<typename A::point3D> &&
concepts::transform3D<typename A::transform3D> &&
concepts::matrix<typename A::template matrix<3, 3>>);

/// Check if an algebra has soa layout
/// @{
template <typename A>
concept soa = (!concepts::arithmetic<algebra::get_scalar_t<A>>);

template <typename A>
concept aos = (!concepts::soa<A>);
/// @}

} // namespace algebra::concepts
32 changes: 32 additions & 0 deletions core/include/detray/algebra/frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Algebra plugins library, part of the ACTS project (R&D line)
#
# (c) 2021-2024 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

# Set up all enabled libraries.
add_subdirectory( array_cmath )

if( ALGEBRA_PLUGINS_INCLUDE_EIGEN )
add_subdirectory( eigen_generic )
add_subdirectory( eigen_eigen )
endif()

if( ALGEBRA_PLUGINS_INCLUDE_SMATRIX )
add_subdirectory( smatrix_generic )
add_subdirectory( smatrix_smatrix )
endif()

if( ALGEBRA_PLUGINS_INCLUDE_VC )
add_subdirectory( vc_aos )
add_subdirectory( vc_aos_generic )
add_subdirectory( vc_soa )
endif()

if( ALGEBRA_PLUGINS_INCLUDE_FASTOR )
add_subdirectory( fastor_fastor )
endif()

if( ALGEBRA_PLUGINS_INCLUDE_VECMEM )
add_subdirectory( vecmem_cmath )
endif()
13 changes: 13 additions & 0 deletions core/include/detray/algebra/frontend/cmath/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Algebra plugins library, part of the ACTS project (R&D line)
#
# (c) 2021-2023 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

# Set up the library.
algebra_add_library( algebra_array_cmath array_cmath
"include/algebra/array_cmath.hpp" )
target_link_libraries( algebra_array_cmath
INTERFACE algebra::common algebra::array_storage algebra::cmath_math algebra::generic_math )
algebra_test_public_headers( algebra_array_cmath
"algebra/array_cmath.hpp" )
153 changes: 153 additions & 0 deletions core/include/detray/algebra/frontend/cmath/include/algebra/cmath.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/** Algebra plugins library, part of the ACTS project
*
* (c) 2020-2024 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

#pragma once

// Project include(s).
#include "algebra/math/cmath.hpp"
#include "algebra/math/generic.hpp"
#include "algebra/math/impl/generic_matrix.hpp"
#include "algebra/storage/array.hpp"

namespace algebra {

/// @name Operators on @c algebra::array::storage_type
/// @{

using algebra::cmath::operator*;
using algebra::cmath::operator-;
using algebra::cmath::operator+;

/// @}

namespace getter {

/// @name Getter functions on @c algebra::array::storage_type
/// @{

using cmath::storage::block;
using cmath::storage::element;
using cmath::storage::set_block;
using cmath::storage::vector;

/// @}

} // namespace getter

namespace vector {

/// @name Vector functions on @c algebra::array::storage_type
/// @{

// array specific implementations
using cmath::dot;
using cmath::normalize;

// generic implementations
using cmath::cross;
using cmath::eta;
using cmath::norm;
using cmath::perp;
using cmath::phi;
using cmath::theta;

/// @}

} // namespace vector

// Use special algorithms for 4 dimensional matrices
namespace generic {

// Determinant algorithms
template <concepts::scalar T, auto ROWS, auto COLS>
struct determinant_selector<4, array::matrix_type<T, ROWS, COLS>,
array::element_getter> {
using type =
matrix::determinant::hard_coded<array::matrix_type<T, ROWS, COLS>,
array::element_getter>;
};

// Inversion algorithms
template <concepts::scalar T, auto ROWS, auto COLS>
struct inversion_selector<4, array::matrix_type<T, ROWS, COLS>,
array::element_getter> {
using type = matrix::inverse::hard_coded<array::matrix_type<T, ROWS, COLS>,
array::element_getter>;
};

} // namespace generic

namespace matrix {

/// @name Matrix functions on @c algebra::array::storage_type
/// @{

using cmath::identity;
using cmath::set_identity;
using cmath::set_zero;
using cmath::zero;

// Uses generic implementation in the background
using cmath::determinant;
using cmath::inverse;
using cmath::transpose;

using generic::math::set_inplace_product_left;
using generic::math::set_inplace_product_left_transpose;
using generic::math::set_inplace_product_right;
using generic::math::set_inplace_product_right_transpose;
using generic::math::set_product;
using generic::math::set_product_left_transpose;
using generic::math::set_product_right_transpose;
using generic::math::transposed_product;

/// @}

} // namespace matrix

namespace array {

/// @name cmath based transforms on @c algebra::array
/// @{

template <concepts::scalar T>
using transform3 =
generic::math::transform3<array::size_type, T, array::matrix_type,
array::storage_type>;

/// @}

} // namespace array

namespace plugin {

/// Define the plugin types
/// @{
template <concepts::value V>
struct array {
/// Define scalar type
using value_type = V;

template <concepts::element T>
using simd = T;

using boolean = bool;
using scalar = value_type;
using size_type = algebra::array::size_type;
using transform3D = algebra::array::transform3<value_type>;
using point2D = algebra::array::point2<value_type>;
using point3D = algebra::array::point3<value_type>;
using vector3D = algebra::array::vector3<value_type>;

template <std::size_t ROWS, std::size_t COLS>
using matrix = algebra::array::matrix_type<value_type, ROWS, COLS>;
};
/// @}

} // namespace plugin

} // namespace algebra
14 changes: 14 additions & 0 deletions core/include/detray/algebra/frontend/eigen/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Algebra plugins library, part of the ACTS project (R&D line)
#
# (c) 2021-2023 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

# Set up the library.
algebra_add_library( algebra_eigen_eigen eigen_eigen
"include/algebra/eigen_eigen.hpp" )
target_link_libraries( algebra_eigen_eigen
INTERFACE algebra::common algebra::eigen_storage algebra::eigen_math algebra::generic_math
Eigen3::Eigen )
algebra_test_public_headers( algebra_eigen_eigen
"algebra/eigen_eigen.hpp" )
Loading
Loading