Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Core/include/Acts/Utilities/detail/CombinatoricIndices.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Utilities/ArrayHelpers.hpp"
0012 #include "Acts/Utilities/MathHelpers.hpp"
0013 
0014 #include <algorithm>
0015 #include <vector>
0016 
0017 namespace Acts::detail {
0018 /// Utility class to loop over all possible ways to draw K unique elements out
0019 /// of a continuous sequence of N elements. The list of combinations starts with
0020 /// the lowest possible set of indices, e.g. for a sequence of 4
0021 ///             [0, 1, 2, 3]
0022 /// The next members of the series increment the (K-1) th index until
0023 ///             [0, 1, 2, N-1].
0024 /// Then the third index is incremented and the last one set to the next value
0025 ///             [0, 1, 3, 4].
0026 /// The sequence continues until all elements are at their maximum value.
0027 ///
0028 /// The user can either loop manually to draw the list of elements
0029 /// or use a range based for loop
0030 template <std::size_t K>
0031 class CombinatoricIndices {
0032  public:
0033   /// Declare the Return type of the Index generator to be an array of size K
0034   using IndexArray = std::array<std::size_t, K>;
0035 
0036   /// Delete default constructor
0037   CombinatoricIndices() = delete;
0038   /// Constructor of the combinatoric indices
0039   /// @param n The size of the set from which indices are drawn
0040   /// @note An exception is thrown if the size is less than the
0041   /// number of indices to draw
0042   explicit CombinatoricIndices(const std::size_t N)
0043     requires(K > 0);
0044 
0045   /// The number of possibilities to draw K different indices from the set
0046   /// @returns The number of combinations
0047   std::size_t size() const;
0048   /// The size of the set from which the indices are drawn
0049   /// @returns The parameter N with which this class was constructed
0050   std::size_t intervalSize() const;
0051 
0052   /// Draws a new combination of indices and stores them in the array
0053   /// @param combination The number of the combination in the sequence
0054   /// @returns An array where each is a unique number from [0; N)
0055   IndexArray draw(const std::size_t combination) const;
0056 
0057   /// Iterator class to be used in the ranged for loop
0058   class iterator {
0059    public:
0060     /// Empty default constructor
0061     iterator() = default;
0062     /// Constructor with a CombinatoricIndex parent and the iterator position
0063     /// @param parent Pointer to the parent used to draw the combinatoric indices
0064     /// @param combination Position of the iterator in the sequence of combinations
0065     iterator(const CombinatoricIndices* parent, const std::size_t combination);
0066 
0067     /// Increment the internal iterator count by one unit
0068     /// @returns Mutable reference to the iterator instance
0069     iterator& operator++();
0070     /// Return an iterator shifted by x indices in the sequence
0071     /// @param idx Number of indexes by which the new operator is shifted from this one
0072     /// @returns A new iterator
0073     iterator operator+(const std::size_t idx) const;
0074 
0075     /// Comparison operator to check whether two iterators are equal,
0076     /// i.e. they share the same parent and have the same internal iterator
0077     /// index
0078     /// @param other Const reference to the other iterator to check
0079     /// @returns The equality assessment of the two iterators
0080     bool operator==(const iterator& other) const;
0081 
0082     /// Comparison operator to check whether two iterators are unequal
0083     /// @param other Const reference to the other iterator to check
0084     /// @returns The inequality assessment of the two iterators
0085     bool operator!=(const iterator& other) const;
0086 
0087     /// Dereference operator to the underlying memory
0088     /// @returns The array containing the unique indices of the combinatoric generator
0089     const IndexArray& operator*() const;
0090 
0091    private:
0092     /// Update the internal array to the current element in the sequence
0093     void updateArray();
0094     /// Pointer to the parent from which the combinatoric indices are drawn
0095     const CombinatoricIndices* m_parent{nullptr};
0096     /// Iterator index in the sequence of iterations
0097     std::size_t m_itr{0ul};
0098     /// Storage for the drawn indices
0099     IndexArray m_array{
0100         filledArray<std::size_t, K>(std::numeric_limits<std::size_t>::max())};
0101   };
0102 
0103   /// @returns the begin iterator of the sequence of combinatoric indices
0104   constexpr iterator begin() const { return iterator{this, 0ul}; }
0105   /// @returns the end iterator of the sequence of combinatoric indices
0106   constexpr iterator end() const { return iterator{this, size()}; }
0107 
0108  private:
0109   /// Draws the unique index
0110   /// @param combination: The number of the combination in the list
0111   ///         of sequences
0112   /// @param slot The positional index of the index inside the returned array
0113   /// @returns A unique index for the n-th combination
0114   std::size_t drawIndex(const std::size_t combination,
0115                         const std::size_t slot) const;
0116 
0117   /// Size of the set from which the combinations can be drawn needs to be >= K
0118   std::size_t m_N{};
0119   /// Cache to state until which member in the sequence of drawn combinations
0120   /// the lowest possible integer can occur in a slot. E.g. for the case N = 5,
0121   /// k = 3 The 0 at the first position is used until combination #6, the 1
0122   /// until combination 6 + 3 = 9 and the 2 until combination  6 + 3 + 1 = 10
0123   std::array<std::vector<std::size_t>, K> m_elementOccurance{};
0124 };
0125 
0126 }  // namespace Acts::detail
0127 
0128 #include "Acts/Utilities/detail/CombinatoricIndices.ipp"