Create the Union of MultiIndexSet
Instances#
import minterpy as mp
import numpy as np
This guide demonstrates how to create the union of MultiIndexSet
instances and shows the convention adopted by Minterpy regarding the union of two multi-indices.
The following three cases are considered:
MultiIndexSet
instances with the same dimensionMultiIndexSet
instances with different dimensionsMultiIndexSet
instances with different \(l_p\)-degrees
The union of MultiIndexSet
instances may be created via a method call (MultiIndexSet.union()
) or an operator (|
or |=
).
Instances with the same dimension#
As a motivating example, consider the following two multi-index sets of the same dimension:
Both sets are defined with respect to the same \(l_p\)-degree of \(1.0\). Notice that both sets are downward-closed.
mi_a = mp.MultiIndexSet(
np.array([[0, 0], [1, 0], [2, 0], [0, 1]]),
lp_degree=1.0,
)
mi_b = mp.MultiIndexSet(
np.array([[0, 0], [0, 1], [0, 2], [0, 3]]),
lp_degree=1.0,
)
The union of these two sets can be constructed using the “or” (|
) operator:
mi_union_1 = mi_a | mi_b
print(mi_union_1)
MultiIndexSet(m=2, n=3, p=1.0)
[[0 0]
[1 0]
[2 0]
[0 1]
[0 2]
[0 3]]
The dimension of the product set remains the same as that of the operands (in this case, \(2\)). Also notice that the union set is lexicographically sorted. Furthermore, because the operands are downward-closed, the resulting union remains downward-closed. That is:
mi_union_1.is_downward_closed
True
The polynomial degree of the product set is:
print(mi_union_1.poly_degree)
3
The union may also be created using a method call (MultiIndexSet.union()
) whose result is equivalent:
mi_union_1 == mi_a.union(mi_b)
True
Note that the multi-index sets do not have to be downward-closed for taking the product. Consider, for instance, a multi-index set that is not downward-closed:
again with respect to \(l_p\)-degree of \(1.0\).
mi_c = mp.MultiIndexSet(
np.array([[1, 0], [0, 3]]),
lp_degree=1.0,
)
The union with the multi-index set \(A\) is:
mi_a | mi_c
MultiIndexSet(
array([[0, 0],
[1, 0],
[2, 0],
[0, 1],
[0, 3]]),
lp_degree=1.0
)
Because one of the operands is not downward-closed, the product set is also not downward-closed. That is:
(mi_a | mi_c).is_downward_closed
False
Instances with different dimensions#
The union may also be carried out for multi-index sets of different dimensions.
Both sets are defined with the same \(l_p\)-degree of \(1.0\).
mi_d = mp.MultiIndexSet(
np.array([[0, 0], [1, 0]]),
lp_degree=1.0,
)
mi_e = mp.MultiIndexSet(
np.array([[0, 0, 0], [1, 0, 0], [0, 0, 1]]),
lp_degree=1.0,
)
The union set is:
mi_union_2 = mi_d | mi_e
print(mi_union_2)
MultiIndexSet(m=3, n=1, p=1.0)
[[0 0 0]
[1 0 0]
[0 0 1]]
Notice that the product set has the same dimension as the largest dimension of the operands (in this case, \(3\)). In other words, the dimensionality of the first operand is expanded.
The polynomial degree of the product set is:
print(mi_union_2.poly_degree)
1
Instances with different \(l_p\)-degrees#
If the union of two multi-index sets with different \(l_p\)-degrees are created, then the \(l_p\)-degrees of the union set is the maximum of the \(l_p\)-degrees of the operands. Consider the following example:
mi_f = mp.MultiIndexSet(
np.array([[0, 0], [1, 0], [1, 0], [1, 1]]),
lp_degree=np.inf,
)
mi_g = mp.MultiIndexSet(
np.array([[0, 0], [1, 0], [0, 1]]),
lp_degree=1.0,
)
The union set is:
mi_union_3 = mi_f | mi_g
print(mi_union_3)
MultiIndexSet(m=2, n=1, p=inf)
[[0 0]
[1 0]
[0 1]
[1 1]]
By convention, the \(l_p\)-degree of the union set is the maximum of the \(l_p\)-degrees of the operands (in this case, \(\infty\)):
print(mi_union_3.lp_degree)
inf
The polynomial degree of the union set is computed based on the resulting index set and \(l_p\)-degree:
print(mi_union_3.poly_degree)
1
In-place union#
The union between two MultiIndexSet
instances may also be created in-place. That is, one of the instance is directly updated by the union of the two instances.
To create the union via an in-place method call, set the inplace
parameter to True
(the default is set to False
):
mi_a.union(mi_b, inplace=True)
The instance mi_a
has been updated in-place:
mi_a == mi_union_1
True
Alternatively, to create the union via an inplace operator:
mi_d |= mi_e
Similarly as before, the instance mi_d
has been updated in-place:
mi_d == mi_union_2
True