multi_index#
This module contains numerical routines for manipulating multi-indices.
- minterpy.utils.multi_index.get_poly_degree(exponents, lp_degree)[source]#
Get the polynomial degree from a multi-index set for a given lp-degree.
- minterpy.utils.multi_index.get_exponent_matrix(spatial_dimension, poly_degree, lp_degree)[source]#
Generate exponent matrix.
- Parameters:
- Returns:
List of exponent arrays for all monomials, whose lp-norm of the exponents is smaller or equal to the given poly_degree. The list is given as a
np.ndarray
with the shape (number_of_monomials, spatial_dimension) and the list is lexicographically ordered.- Return type:
np.ndarray
- minterpy.utils.multi_index.gen_backward_neighbors(index)[source]#
Yield the backward neighbors of a given multi-index set element.
- Parameters:
index (
numpy.ndarray
) – Multi-index set element (i.e., a vector of multi-indices), a one-dimensional array of lengthm
, wherem
is the spatial dimensions.- Returns:
A generator that yields all the backward neighbors (i.e., all vectors of multi-indices “smaller by 1”) of the given multi-index element.
- Return type:
Iterable
[numpy.ndarray
]
Examples
>>> my_backward_neighbors = gen_backward_neighbors(np.array([1, 1, 2])) >>> for my_backward_neighbor in my_backward_neighbors: ... print(my_backward_neighbor) [0 1 2] [1 0 2] [1 1 1]
- minterpy.utils.multi_index.gen_missing_backward_neighbors(indices)[source]#
Yield all the missing backward neighbors for an array of multi-indices.
- Parameters:
indices (
numpy.ndarray
) – Array of lexicographically sorted multi-indices, a two-dimensional non-negative integer array of shape(N, m)
, whereN
is the number of multi-indices andm
is the number of spatial dimensions.- Returns:
A generator that yields all the missing backward neighbors (i.e., all the missing vectors of multi-indices “smaller by 1”) of the array of multi-indices.
- Return type:
Iterable
[numpy.ndarray
]
Notes
This function strictly requires a lexicographically sorted array of multi-indices but, as a utility function, it does not check for them for efficiency reason. Higher-level functions that call this function must make sure that the array is sorted beforehand.
Examples
>>> my_missing_neighbors = gen_missing_backward_neighbors(np.array([[3]])) >>> for missing_neighbor in my_missing_neighbors: ... print(missing_neighbor) [2] >>> my_missing_neighbors = gen_missing_backward_neighbors( ... np.array([[1, 1, 1]]) ... ) >>> for missing_neighbor in my_missing_neighbors: ... print(missing_neighbor) [0 1 1] [1 0 1] [1 1 0]
- minterpy.utils.multi_index.is_complete(indices, poly_degree, lp_degree)[source]#
Check if an array of multi-indices is complete w.r.t poly- & lp-degree.
- Parameters:
indices (
numpy.ndarray
) – Array of lexicographically sorted multi-indices, a two-dimensional non-negative integer array of shape(N, m)
, whereN
is the number of multi-indices andm
is the number of spatial dimensions.poly_degree (int) – Polynomial degree supported by the multi-index set.
lp_degree (float) – \(p\) in the \(l_p\)-norm with respect to which the multi-index set is defined.
- Returns:
True
if the multi-index set is complete andFalse
otherwise. The function also returnsFalse
if the array of multi-indices is not lexicographically sorted (including containing any duplicate entries).- Return type:
Notes
For a definition of completeness, refer to the relevant section of the Minterpy Documentation.
Examples
>>> my_indices = np.array([ ... [0, 0, 0], ... [1, 0, 0], ... [0, 1, 0], ... [1, 1, 0], ... [0, 0, 1], ... [1, 0, 1], ... [0, 1, 1], ... [1, 1, 1]]) >>> is_complete(my_indices, poly_degree=1, lp_degree=np.inf) True >>> is_complete(my_indices, poly_degree=1, lp_degree=2.0) False >>> is_complete(my_indices, poly_degree=2, lp_degree=1.0) False
- minterpy.utils.multi_index.is_disjoint(indices_1, indices_2, expand_dim_=False)[source]#
Check if an array of multi-indices is disjoint with another.
- Parameters:
indices_1 (
numpy.ndarray
) – Two-dimensional integer array of shape(N1, m)
, whereN1
is the number of multi-indices andm
is the number of spatial dimensions.indices_2 (
numpy.ndarray
) – Two-dimensional integer array of shape(N2, m)
, whereN2
is the number of multi-indices andm
is the number of spatial dimensions.expand_dim (bool, optional) – Flag to allow the spatial dimension (i.e., the number of columns) of the indices to be expanded if there is a difference.
expand_dim_ (bool)
- Returns:
True
if the multi-index sets are disjoint andFalse
otherwise. The function also returnsTrue
if the number of columns are different andexpand_dim
is set toFalse
.- Return type:
Examples
>>> my_indices_1 = np.array([ ... [0, 0, 0], ... [1, 0, 0], ... [1, 1, 1]]) >>> my_indices_2 = np.array([ ... [0, 0, 0], ... [1, 1, 1]]) >>> is_disjoint(my_indices_1, my_indices_2) False >>> my_indices_3 = np.array([ ... [2, 0, 1], ... [1, 2, 1]]) >>> is_disjoint(my_indices_1, my_indices_3) True >>> my_indices_4 = np.array([ ... [0, 0], ... [1, 0]]) >>> is_disjoint(my_indices_1, my_indices_4) True >>> is_disjoint(my_indices_1, my_indices_4, expand_dim_=True) False
- minterpy.utils.multi_index.is_downward_closed(indices)[source]#
Check if an array of multi-indices is downward-closed.
- Parameters:
indices (
numpy.ndarray
) – Array of lexicographically sorted multi-indices, a two-dimensional non-negative integer array of shape(N, m)
, whereN
is the number of multi-indices andm
is the number of spatial dimensions.- Returns:
True
if the multi-index set is downward-closed andFalse
otherwise. The function also returnsFalse
if the array of multi-indices is not lexicographically sorted (including containing any duplicate entries).- Return type:
Notes
A multi-index is downward-closed if it does not contain “hole” across its spatial dimensions.
Some synonyms for a downward-closed multi-index set are: “monotonic”, “lower”, or “lexicographically complete”.
Examples
>>> my_indices = np.array([ ... [0, 0, 0], ... [1, 0, 0], ... [0, 0, 1]]) >>> is_downward_closed(my_indices) True >>> my_indices = np.array([ ... [0, 0, 0], ... [1, 0, 0], ... [0, 2, 0]]) # missing [0, 1, 0] >>> is_downward_closed(my_indices) False
- minterpy.utils.multi_index.list_insert_single(list_of_indices, index2insert, check_for_inclusion=True)[source]#
inserts a single index into a given list of indices maintaining lexicographical ordering
- minterpy.utils.multi_index.insert_lexicographically(indices, indices2insert)[source]#
inserts possibly multiple index vectors into a given array of indices maintaining lexicographical ordering
- exploits ordering for increased efficiency:
inserts one vector after another to maintain ordering
- NOTE: is expected to return the same identical array instance
if all exponents are already contained!
- minterpy.utils.multi_index.make_derivable(indices)[source]#
inserts all missing multi index vectors “smaller by one”
- minterpy.utils.multi_index.make_complete(exponents, lp_degree)[source]#
Create a complete exponents from a given array of exponents.
A complete set of exponents contains all monomials, whose \(l_p\)-norm of the exponents are smaller or equal to the polynomial degree of the set.
- Parameters:
exponents (
numpy.ndarray
) – A given exponent array to be completed.lp_degree (
float
) – A given \(l_p\) of the \(l_p\)-norm (i.e., the lp-degree) for the completion.
- Returns:
The complete exponents with respect to the given
exponents
andlp_degree
.- Return type:
Notes
The polynomial degree is inferred from the given exponents with respect to the required
lp_degree
. It is the smallest polynomial degree with respect to thelp_degree
to contain the given exponents.
Examples
>>> exponent = np.array([[2, 2]]) >>> lp_degree = 2.0 >>> make_complete(exponent, lp_degree) # Complete w.r.t the lp_degree array([[0, 0], [1, 0], [2, 0], [3, 0], [0, 1], [1, 1], [2, 1], [0, 2], [1, 2], [2, 2], [0, 3]])
- minterpy.utils.multi_index.make_downward_closed(indices)[source]#
Make an array of multi-indices downward-closed.
- Parameters:
indices (
numpy.ndarray
) – Array of lexicographically sorted multi-indices, a two-dimensional non-negative integer array of shape(N, m)
, whereN
is the number of multi-indices andm
is the number of spatial dimensions.- Returns:
Array of downward-closed lexicographically sorted multi-indices, a two-dimensional array of shape
(N1, m)
, whereN1
is the number of multi-indices in the downward-closed set andm
is the number of spatial dimensions.- Return type:
Notes
This function strictly requires a lexicographically sorted array of multi-indices but, as a utility function, it does not check for them for efficiency reason. Higher-level functions that call this function must make sure that the array is sorted beforehand.
Examples
>>> my_indices = np.array([ ... [0, 0], ... [2, 0], # Jump from [1, 0] ... [0, 3], # Jump from [0, 1] and [0, 2] ... ]) >>> make_downward_closed(my_indices) array([[0, 0], [1, 0], [2, 0], [0, 1], [0, 2], [0, 3]]) >>> my_indices = np.array([[1, 1, 1]]) # must be two-dimensional >>> make_downward_closed(my_indices) array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]])
- minterpy.utils.multi_index.find_match_between(smaller_idx_set, larger_idx_set)[source]#
find the positions of each multi_index of the smaller set in the larger set
NOTE: both sets are required to be ordered lexicographically! NOTE: the smaller set is required to be a subset of the larger set NOTE: this function is required for ‘rebasing’ a polynomial onto complete multi indices (map the coefficients)
- minterpy.utils.multi_index.lex_sort(indices)[source]#
Lexicographically sort an array of multi-indices.
- Parameters:
indices (
numpy.ndarray
) – Two-dimensional array of multi-indices to be sorted.- Returns:
Lexicographically sorted array, having the same type as
indices
. Only unique entries are kept in the sorted array.- Return type:
Examples
>>> xx = np.array([ ... [0, 1, 2, 3], ... [0, 1, 0, 1], ... [0, 0, 0, 0], ... [0, 0, 1, 1], ... [0, 0, 0, 0], ... ]) >>> lex_sort(xx) # Sort and remove duplicates array([[0, 0, 0, 0], [0, 1, 0, 1], [0, 0, 1, 1], [0, 1, 2, 3]])
- minterpy.utils.multi_index.multiply_indices(indices_1, indices_2)[source]#
Multiply an array of multi-indices with another array of multi-indices.
- Parameters:
indices_1 (
numpy.ndarray
) – Two-dimensional array of multi-indices of shape(N1, m2)
whereN1
is the number of multi-indices andm2
is the number of dimensions of the first array.indices_2 (
numpy.ndarray
) – Another two-dimensional array of multi-indices of shape(N2, m2)
whereN2
is the number of multi-indices andm2
is the number of dimensions of the second array.
- Returns:
The product of
indices_1
withindices_2
of shape(N3, m3)
wherem3
is the maximum betweenm1
andm2
. The product array is lexicographically sorted.- Return type:
Examples
>>> my_indices_1 = np.array([ ... [0, 0], ... [1, 0], ... [0, 1], ... [1, 1], ... ]) >>> my_indices_2 = np.array([ ... [0, 0], ... [1, 0], ... [0, 1], ... ]) >>> multiply_indices(my_indices_1, my_indices_2) array([[0, 0], [1, 0], [2, 0], [0, 1], [1, 1], [2, 1], [0, 2], [1, 2]]) >>> my_indices_3 = np.array([ ... [0], ... [1], ... [2], ... ]) >>> multiply_indices(my_indices_2, my_indices_3) # Different dimension array([[0, 0], [1, 0], [2, 0], [3, 0], [0, 1], [1, 1], [2, 1]]) >>> my_indices_4 = np.empty((0, 2), dtype=INT_DTYPE) >>> multiply_indices(my_indices_3, my_indices_4) # empty set array([], shape=(0, 2), dtype=int64)
- minterpy.utils.multi_index.union_indices(indices_1, indices_2)[source]#
Create a union between two arrays of multi-indices.
- Parameters:
indices_1 (
numpy.ndarray
) – Two-dimensional array of multi-indices of shape(N1, m2)
whereN1
is the number of multi-indices andm2
is the number of dimensions of the first array.indices_2 (
numpy.ndarray
) – Another two-dimensional array of multi-indices of shape(N2, m2)
whereN2
is the number of multi-indices andm2
is the number of dimensions of the second array.
- Returns:
The union of
indices_1
andindices_2
of shape(N3, m3)
wherem3
is the maximum betweenm1
andm2
. The union is lexicographically sorted.- Return type:
Examples
>>> my_indices_1 = np.array([ ... [0, 0], ... [1, 0], ... [0, 1], ... [1, 1], ... ]) >>> my_indices_2 = np.array([ ... [0, 0], ... [1, 0], ... [0, 1], ... ]) >>> union_indices(my_indices_1, my_indices_2) array([[0, 0], [1, 0], [0, 1], [1, 1]]) >>> my_indices_3 = np.array([ ... [0], ... [1], ... [2], ... ]) >>> union_indices(my_indices_1, my_indices_3) # Different dimension array([[0, 0], [1, 0], [2, 0], [0, 1], [1, 1]]) >>> my_indices_4 = np.empty((0, 1), dtype=int) >>> union_indices(my_indices_3, my_indices_4) array([[0], [1], [2]])