Add Exponents to a Multi-Index Set#

import minterpy as mp
import numpy as np

An additional exponent or a set of exponents may be added to an already created MultiIndexSet instance. This guide shows you how.

Motivating example#

Suppose we have a complete multi-index set for multivariate polynomials of dimension \(4\), degree \(2\), and \(l_p\)-degree \(1.0\):

mi = mp.MultiIndexSet.from_degree(4, 2, 1)
print(mi)
MultiIndexSet(m=4, n=2, p=1.0)
[[0 0 0 0]
 [1 0 0 0]
 [2 0 0 0]
 [0 1 0 0]
 [1 1 0 0]
 [0 2 0 0]
 [0 0 1 0]
 [1 0 1 0]
 [0 1 1 0]
 [0 0 2 0]
 [0 0 0 1]
 [1 0 0 1]
 [0 1 0 1]
 [0 0 1 1]
 [0 0 0 2]]

Add an exponent to a MultiIndexSet instance#

The method add_exponents() inserts an exponent to a MultiIndexSet instance. The exponents must be given as a NumPy integer array of the correct dimension.

Suppose now we’d like to add a new exponent element \(\left( 0, 0, 3, 0 \right)\):

new_exp = np.array([[0, 0, 3, 0]], dtype=int)
new_exp
array([[0, 0, 3, 0]])

Notice that the array is of shape \(1 \times 4\) because the dimension of the multi-index set is \(4\) and one new element is to be added. To add the exponent to the MultiIndexSet instance:

mi.add_exponents(new_exp)
MultiIndexSet(
  array([[0, 0, 0, 0],
         [1, 0, 0, 0],
         [2, 0, 0, 0],
         [0, 1, 0, 0],
         [1, 1, 0, 0],
         [0, 2, 0, 0],
         [0, 0, 1, 0],
         [1, 0, 1, 0],
         [0, 1, 1, 0],
         [0, 0, 2, 0],
         [0, 0, 3, 0],
         [0, 0, 0, 1],
         [1, 0, 0, 1],
         [0, 1, 0, 1],
         [0, 0, 1, 1],
         [0, 0, 0, 2]]),
  lp_degree=1.0
)

The new exponent is lexicographically added to the previous set of exponents. In the example above, the element \(\left( 0, 0, 3, 0 \right)\) comes right after \(\left( 0, 0, 2, 0 \right)\) and before \(\left( 0, 0, 0, 1 \right)\).

The method add_exponents() returns a new instance of MultiIndexSet with extended exponents; the change does not happen in-place and should be stored in a different variable for later usage:

mi_ext = mi.add_exponents(new_exp)
print(mi_ext)
MultiIndexSet(m=4, n=3, p=1.0)
[[0 0 0 0]
 [1 0 0 0]
 [2 0 0 0]
 [0 1 0 0]
 [1 1 0 0]
 [0 2 0 0]
 [0 0 1 0]
 [1 0 1 0]
 [0 1 1 0]
 [0 0 2 0]
 [0 0 3 0]
 [0 0 0 1]
 [1 0 0 1]
 [0 1 0 1]
 [0 0 1 1]
 [0 0 0 2]]

Notice that the new instance has a higher polynomial degree than the original degree:

mi_ext.poly_degree
3

This degree corresponds to the degree \(n\) such that the \(l_p\)-norm \(\lVert \boldsymbol{\alpha} \rVert_{p} = (\alpha_1^p + \alpha_2^p + \alpha_3^p + \alpha_4^p)^{\frac{1}{p}} \leq n\) for all \(\boldsymbol{\alpha} \in A\) holds.

Add a set of exponents to a MultiIndexSet instance#

The method add_exponents() also supports multiple exponents. For instance, the following exponents can be added:

\[ B = \left\{ (3, 0, 0, 0), (0, 3, 0, 0), (0, 0, 0, 3) \right\} \]
exps = np.array([
    [3, 0, 0, 0],
    [0, 3, 0, 0],
    [0, 0, 0, 3],
])
mi.add_exponents(exps)
MultiIndexSet(
  array([[0, 0, 0, 0],
         [1, 0, 0, 0],
         [2, 0, 0, 0],
         [3, 0, 0, 0],
         [0, 1, 0, 0],
         [1, 1, 0, 0],
         [0, 2, 0, 0],
         [0, 3, 0, 0],
         [0, 0, 1, 0],
         [1, 0, 1, 0],
         [0, 1, 1, 0],
         [0, 0, 2, 0],
         [0, 0, 0, 1],
         [1, 0, 0, 1],
         [0, 1, 0, 1],
         [0, 0, 1, 1],
         [0, 0, 0, 2],
         [0, 0, 0, 3]]),
  lp_degree=1.0
)

As before the new exponents are added lexicographically to the existing set of exponents. As mentioned, the method returns a new instance and does not modify the current instance in place.