MultiIndexSet#

class MultiIndexSet#

A class for holding, sorting, and adapting sets of multiindices.

This class is a tool for defining such a multiindex set, relating members within the set (i.e. definingneighbors), and expanding the set.

Public Types

std::function< bool(MultiIndex const  &) LimiterType )

Public Functions

MultiIndexSet(const unsigned int lengthIn, LimiterType const &limiterIn = MultiIndexLimiter::None(), std::shared_ptr<MultiIndexNeighborhood> neigh = std::make_shared<DefaultNeighborhood>())#

Construct a new MultiIndexSet object with a specific length.

Constructs an empty MultiIndexSet to store multi-indices of a specified length. Also allows a functor to be be passed in as an additional limiter on the admissible set. If no functor is provided, it is possible to include any multi-index in \(\mathbb{N}^D\).

For example, to construct a MultiIndexSet in 2 dimensions that only allows multi-indices with maximum degree less than 5, we could use a lambda function:

unsigned int length =2;
auto limiter = [](MultiIndex const& multi) {return multi.Max()<5;};
MultiIndexSet set(length, limiter);
Multiple pre-defined limiter functors are defined in the mpart::MultiIndexLimiter namespace.

Parameters:
  • lengthIn[in] The length of each multi-index in the set.

  • limiterIn[in] An optional functor defining the possible admissible multi-indices. Should accept a const& to MultiIndex and return a boolean. True if the MultiIndex is allowed and false otherwise.

  • neigh[in] A shared_ptr to a child of the MultiIndexNeighborhood class that defines the connectivity between different multiindices. Defaults to DefaultNeighborhood, which defines forward and backward neighbors as multiindices that differ in a single component by a 1.

MultiIndexSet(Eigen::Ref<const Eigen::MatrixXi> const &multis)#

Each row of the input matrix is a multiindex.

FixedMultiIndexSet<Kokkos::HostSpace> Fix(bool compress = true) const#

Converts this multiindex set into the fixed representation provided by the “FixedMultiIndexSet” class.

The FixedMultiIndexSet cannot easily be adapted, but stores the multiindices in a contiguous block of memory in a Kokkos::View that can be more amenable to fast computation. This function creates an instance of the FixedMultiIndexSet from the current state of *this. Note that memory is deep copied and any subsequent updates to this class will not result in updates to the FixedMultiIndexSet.

Parameters:

compress[in] Should the fixed representation be in compressed format?

Returns:

An instance of the FixedMultiIndexSet class with a snapshot of the current state of this MultiIndexSet.

MultiIndexSet Cartesian(MultiIndexSet const &otherSet, LimiterType const &limiter = MultiIndexLimiter::None()) const#

Constructs a new MultiIndexSet containing the outer (tensor) product of this set with another. Consider two multiindex sets: \(\mathcal{M}_1 \subset \mathbb{N}^{D_1}\) containing multiindices of length \(D_1\) and \(\mathcal{M}_2 \subset \mathbb{N}^{D_2}\) containing multiindices of length \(D_2\). The filtered Cartesian product defined by this function is given by

\[ \mathcal{M}_1 \bigtimes \mathcal{M}_2 = \{[\alpha_1,\alpha_2] \mid \quad \forall \alpha_1\in\mathcal{M}_1,\,\alpha_2\in\mathcal{M}_2 \text{ and } F([\alpha_1,\alpha_2])=1\}, \]
where \(F([\alpha_1,\alpha_2])\) is and indicator of whether the term should ultimately be included in the product set or not. Here, this indicator function is defined through the limiter function

void SetLimiter(LimiterType const &limiterIn)#

Set the limiter of this MultiIndexSet. This function will check to make sure that all currently active nodes are still feasible with the new limiter. If this is not the case, an assert will be thrown.

Parameters:

limiterIn[in] A functor that accepts a MultiIndex and returns a boolean if it is allowed in the set.

inline LimiterType GetLimiter() const#

Returns the limiter used in this MultiIndexSet.

inline MultiIndex IndexToMulti(unsigned int activeIndex) const#

Given an index into the set, return the corresponding multiindex as an instance of the MultiIndex set. If all the multiindices were stored in a vector called multiVec, the functionality of this method would be equivalent to multiVec[activeIndex].

Parameters:

activeIndex[in] Linear index of interest.

Returns:

A constant reference to the MultiIndex.

int MultiToIndex(MultiIndex const &input) const#

Given a multiindex, return the linear index where it is located.

Parameters:

input[in] An instance of the MultiIndex class.

Returns:

If the multiindex was found in this set, a nonnegative value containing the linear index is returned. However, if the set does not contain the multiindex, -1 is returned.

inline unsigned int Length() const#

Get the dimension of the multiindex, i.e. how many components does it have?

inline std::vector<unsigned int> const &MaxOrders() const#

Assume the \(\mathbf{j}^{\mbox{th}}\) multiindex in this set is given by \(\mathbf{j}=[j_1,j_2,\dots,j_D]\). This function returns a vector containing the maximum value of any multiindex in each direction, i.e., a vector \(\mathbf{m}=[m_1,m_2,\dots,m_D]\) where \(m_d = \max_{\mathbf{j}} j_d\).

Returns:

The vector \(\mathbf{m}\).

inline MultiIndex at(int activeIndex) const#

This function provides access to each of the MultiIndices.

Parameters:

activeIndex[in] The index of the active MultiIndex to return.

Returns:

A pointer to the MultiIndex at index outputIndex.

inline MultiIndex const &operator[](int activeIndex) const#

This function provides access to each of the MultiIndices without any bounds checking on the vector.

Parameters:

outputIndex[in] The index of the active MultiIndex we want to return.

Returns:

A pointer to the MultiIndex at index outputIndex.

inline unsigned int Size() const#

Get the number of active MultiIndices in this set.

Returns:

An unsigned integer with the number of active MultiIndices in the set.

bool operator==(const MultiIndexSet &b) const#

Check to see if sets have the same active terms.

MultiIndexSet &operator+=(const MultiIndexSet &rhs)#

Add another set of multiindices to this one.

Any multiindices the rhs MultiIndexSet not already in (*this) are added. After calling this function, *this will contain the union or the two sets.

Parameters:

rhs[in] Another MultiIndex set to add to this one

Returns:

A reference to this MultiIndex set, which now contains the union of this set and rhs.

MultiIndexSet &operator+=(MultiIndex const &rhs)#

Add a single MultiIndex to the set.

This functions checks to see if the input basis function is already in the set and if the input function is unique, it is added to the set.

Parameters:

rhs[in] The MultiIndex we want to add to the set.

Returns:

A reference to this MultiIndex, which may now contain the new MultiIndex in rhs.

MultiIndexSet &operator=(const MultiIndexSet &rhs)#

Assignment operator. Will throw a runtime_error exception if the rhs does not have the same size of *this.

std::vector<bool> FilterBounded(const MultiIndex &bound) const#

Checks which MultiIndices exceed a given MultiIndex bound

unsigned int Union(const MultiIndexSet &rhs)#

Add all terms in rhs to this instance.

This function adds all unique MultiIndices from the rhs into this MultiIndexSet. In the event that a multiindex is active in one set, but not the other, the union will set that multiindex to be active.

Parameters:

rhs[in] The MultiIndex set we want to add to this instance.

Returns:

The number of unique terms from rhs that were added to this set.

void Activate(MultiIndex const &multiIndex)#

Make the multi-index active. If the multiIndex is not admissable, an exception will be thrown. To be admissable (according to this function), the multiIndex must already exist as an inactive member of this set. If that is not the case, use the AddActive function instead.

Parameters:

multiIndex[in] A multiindex to make active. Note that an assert will fail if multiIndex is not admissable.

int AddActive(MultiIndex const &newNode)#

Add the given multiindex to the set and make it active. The functionality of this function is very similar to Activate; however, this function will add the multiIndex if it does not already exist in the set. This function does not check for admissability. Instead, it will add the multiindex to the set and add all neighbors as inactive. Be careful when using this function as it is possible to create a set with active multiindices that are not admisable.

Parameters:

newNode[in] A multiindex we want to add as an active member of the set.

Returns:

An integer specifying the linear index of the now active multiindex.

std::vector<unsigned int> Expand(unsigned int activeIndex)#

If possible, make the neighbors of this index active, and return any that become active. Do not activate a neighbor that is already part of the family.

Parameters:

activeIndex – The linear index of the active multiindex to expand.

Returns:

A vector containing the linear index of any multiindices activated because of the expansion.

std::vector<unsigned int> Expand()#

Activate any inactive but admissible forward neighbors of MultiIndices on the frontier.

Returns:

A vector containing the linear index of any multiindices activated because of this expansion.

std::vector<unsigned int> ForciblyExpand(unsigned int const activeIndex)#

Completely expands an index, whether or not it is currently expandable. In order to maintain admissability of the set, it will add backward neighbors needed recursively, and return a list of all the indices it adds.

Parameters:

activeIndex – The linear index of the active multiindex to expand.

Returns:

A vector containing the linear index of any multiindices activated because of the expansion.

std::vector<unsigned int> ForciblyActivate(MultiIndex const &multiIndex)#

Add the given multi-index to the active set regardless of whether it’s currently admissible. To keep the whole set admissible, recursively add any backward neighbors necessary. Returns a list of indices of any newly added elements, including itself.

Parameters:

multiIndex – The MultiIndex to forcibly add, make active, and make admissable.

Returns:

A vector of linear indices indicating all the active MultiIndices added to the set in order to make the given multiIndex admissable.

std::vector<MultiIndex> AdmissibleForwardNeighbors(unsigned int activeIndex)#

This function returns the admissable forward neighbors of an active multiindex.

Parameters:

activeIndex[in] The linear index of the active multiIndex under consideration.

Returns:

A vector of admissible forward neighbors.

std::vector<unsigned int> Frontier() const#

Here, we define a term on the “frontier” of the multiindex set as one that has at least one inactive admissable forward neighbors. These terms are expandable. Note that a forward neighbor must be admissible according to the limiter currently in place to be considered in the definition of the frontier.

Returns:

A vector with linear indices for active multi-indices on the frontier.

std::vector<MultiIndex> Margin() const#

Returns multiindices in the margin of the set. The margin contains multiindices in the limiting set that also have at least one active backward neighbor.

Returns:

A std::vector containing the multiindices in the margin

std::vector<MultiIndex> ReducedMargin() const#

Returns multiindices in the reduced margin of the set. A multiindex is in the reduced margin if it is in the limiting set and all of its backward neighbors are active.

Returns:

A std::vector containing the multiindices in the reduced margin

std::vector<MultiIndex> ReducedMarginDim(unsigned int dim) const#

Returns multiindices in reduced margin incrementing dim. Will admit multiindices that have any backward neighbor where the given entry in the given dimension is lower.

See also

ReducedMargin().

Parameters:

dim[in] The dimension of the reduced margin to return.

Returns:

A std::vector containing the multiindices in the reduced margin

std::vector<unsigned int> StrictFrontier() const#

We define the strict frontier to be the collection of multiindices, where all admissible forward neighbors are inactive.

Returns:

A vector with linear indices for active multi-indices on the strict frontier.

std::vector<unsigned int> BackwardNeighbors(unsigned int activeIndex) const#

Returns the indices for the backward neighbors of a currently active multiindex.

Parameters:

activeIndex[in] The linear index of the MultiIndex of interest

Returns:

A std::vector containing the linear indices of the backward neighbors.

std::vector<unsigned int> BackwardNeighbors(MultiIndex const &multiIndex) const#

Returns indices for backward neighbors of an active or inactive multiindex.

Parameters:

multiIndex[in] The multiindex in question.

Returns:

A vector with linear indices for the backward neighbors of this multiindex.

bool IsAdmissible(MultiIndex const &multiIndex) const#

Determines whether the input multiIndex is currently admissible.

Parameters:

multiIndex[in] The multiindex to consider.

Returns:

true if the multiIndex is admissible. false otherwise.

bool IsExpandable(unsigned int activeIndex) const#

Check to see if any forward neighbors of a multiIndex are admissible but not active.

Parameters:

activeIndex[in] The linear index of the multi-index in question.

Returns:

true if this multiindex has at least one admissible but inactive forward neighbor.

bool IsActive(MultiIndex const &multiIndex) const#

Return true if the multiIndex is active.

unsigned int NumActiveForward(unsigned int activeInd) const#

Returns the number of active forward neighbors.

unsigned int NumForward(unsigned int activeInd) const#

Returns the number of forward neighbors (active or inactive)

std::vector<unsigned int> NonzeroDiagonalEntries() const#

Finds all active indices in the multiindex set that have a nonzero value in the last dimension.

Returns:

std::vector<unsigned int> A vector of linear indices of active multiindices with nonzero last component

void Visualize(std::ostream &out = std::cout) const#

Visualizes a two-dimensional MultiIndexSet as ASCII art using “a” to denote active multiindices, “r” to denoted multiindices in the reduced margin (not active), and “m” to denoted multiindices in the margin (also not active). Note that the MultiIndexSet::at and MultiIndexSet::IndexToMulti only provide access to the active multiindices. The inactive multiindices in the margin are typically only used for adaptation.

The output for a total order limited set with max order 11 looks like

12 | r
11 | a  r
10 | a  a  r
 9 | a  a  a  r
 8 | a  a  a  a  r
 7 | a  a  a  a  a  r
 6 | a  a  a  a  a  a  r
 5 | a  a  a  a  a  a  a  r
 4 | a  a  a  a  a  a  a  a  r
 3 | a  a  a  a  a  a  a  a  a  r
 2 | a  a  a  a  a  a  a  a  a  a  r
 1 | a  a  a  a  a  a  a  a  a  a  a  r
 0 | a  a  a  a  a  a  a  a  a  a  a  a  r
    ----------------------------------------
     0  1  2  3  4  5  6  7  8  9  10 11 12

Another example for an adaptively constructed set is

4 | r
3 | a  m
2 | a  r
1 | a  a  r  m
0 | a  a  a  a  r
   ----------------
    0  1  2  3  4

The following is the same set as before, but with a multiindex limiter preventing expansion of mixed terms

4 | r
3 | a
2 | a
1 | a  a
0 | a  a  a  a  r
   ----------------
    0  1  2  3  4

Parameters:

out[inout] The output stream where the visualization should be written. Defaults to std::cout.

Public Static Functions

static MultiIndexSet CreateTotalOrder(unsigned int length, unsigned int maxOrder, LimiterType const &limiter = MultiIndexLimiter::None())#

Factory method for constructing a total order limited multiindex set.

Parameters:
  • length[in] The length of the multiindices stored in this set.

  • maxOrder[in] The maximum order of multiindices to include.

  • limiter[in] An optional additional limiter to attach to the set. Only multiindices that satisfy this limiter will be included.

Returns:

MultiIndexSet An instance of the MultiIndexSet class containing all multiindices of order <= maxOrder AND satisfying the limiter.

static MultiIndexSet CreateTensorProduct(unsigned int length, unsigned int maxOrder, LimiterType const &limiter = MultiIndexLimiter::None())#

Factory method for constructing a full tensor product multiindex set.

Parameters:
  • length[in] The length of the multiindices stored in this set.

  • maxDegree[in] The maximum value allowed in any multiindex.

  • limiter[in] An optional additional limiter to attach to the set. Only multiindices that satisfy this limiter will be included.

Returns:

MultiIndexSet An instance of the MultiIndexSet class containing all multiindices with components a_i <= maxDegree AND satisfying the limiter.

Friends

inline friend MultiIndexSet operator+(MultiIndexSet lhs, const MultiIndexSet &rhs)#
inline friend MultiIndexSet operator+(MultiIndexSet lhs, const MultiIndex &rhs)#