Create a multivariate basis of functions from scalar multivariable functions

Description

We want to build a finite basis of functions \mathcal{B}=\{f_1,...,f_n\} where each f_i: \mathbb{R}^d \mapsto \mathbb{R}^q with d>1, q>1, from given scalar multivariable functions g_i: \mathbb{R}^d \mapsto \mathbb{R}.

In other words, we want to create a basis of functions having both a multivariate input and output from functions having a multivariate input and a scalar output.

In this example, we do that by the aggregation of the given functions g_i, using the AggregatedFunction class. This class allows one to create a multivariate output function from a list of functions having a univariate output dimension. Note that we can only aggregate functions that share the same input space.

We illustrate two cases that differ from the way the functions g_i have been created:

  • Case 1: we suppose that the functions g_i have no particular origin,

  • Case 2: we suppose that the functions g_i have been built from particular bases.

In both cases, we use the Basis class to create the basis and the AggregatedFunction class to create a multivariate output function from a list of scalar multivariable functions.

Case 1: Aggregation of given functions

In that case, we have some functions g_i: \mathbb{R}^d \mapsto \mathbb{R} and we aggregate them in order to build the basis \mathcal{B}.

For example, we set d=2, q=3 and we use the functions (g_1, g_2, g_3) defined by:

\begin{array}{lcl}
  g_1(x_1, x_2) & = & 1\\
  g_2(x_1, x_2) & = & x_1 + x_2\\
  g_3(x_1, x_2) & = & x_1^2 + x_2^2
\end{array}

and we want to build the finite basis \mathcal{B}=\{f_1,f_2\} defined by:

\begin{array}{lcl}
  f_1(x_1, x_2) & = & (1, 1, 1)\\
  f_2(x_1, x_2) & = & (1, x_1 + x_2, x_1^2 + x_2^2)
\end{array}

import openturns as ot
d = 2
q = 3

# Create the functions g_i
g_1 = ot.SymbolicFunction(['x1', 'x2'], ['1'])
g_2 = ot.SymbolicFunction(['x1', 'x2'], ['x1+x2'])
g_3 = ot.SymbolicFunction(['x1', 'x2'], ['x1^2+x2^2'])

# Create the multivariate basis
f_1 = ot.AggregatedFunction([g_1] * q)
f_2 = ot.AggregatedFunction([g_1, g_2, g_3])
basis = ot.Basis([f_1, f_2])
print('Fonction f_1 : ', basis.build(0))
Fonction f_1 :  [[x1,x2]->[1],[x1,x2]->[1],[x1,x2]->[1]]

Case 2: Aggregation of functions built from given bases

In that case, we use some functions g_i: \mathbb{R}^d \mapsto \mathbb{R} that have been built from particular bases. For example, they are members of polynomial families which are orthonormal to given distributions.

In this example, we use both polynomial families:

  • (g_1^i)_{i\geq 0} which is a orthonormal multivariate polynomial basis with respect to the uniform distributipn on [-1,1]^d (it is obtained through a tensor product of univariate Legendre polynomials orthonormal with respect to the uniform distribution on [-1,1]),

  • (g_2^i)_{i\geq 0} which is a orthonormal multivariate polynomial basis with respect to the multivariate standard normal distribution (it is obtained through a tensor product of univariate Hermite polynomials orthonormal with respect to the standard normal univariate distribution).

We consider the linear enumeration of the polynomial family. The functions f_i are built as the aggregation of the i-th polynomials of the families (g_1^k)_k and (g_2^k)_k. We only consider g_1^i and g_2^i of total degree less than 2: then we have 6 polynomials f_i.

We still set d=2, q=3.

d = 2

legendre_builder = ot.OrthogonalProductPolynomialFactory([ot.LegendreFactory()] * d)
hermite_builder = ot.OrthogonalProductPolynomialFactory([ot.HermiteFactory()] * d)

# Generate the multivariate functions f_i (quadratic)
total_deg = 2
basis_size = ot.LinearEnumerateFunction(d).getStrataCumulatedCardinal(total_deg)
basis = []
for i in range(basis_size):
    f_i = ot.AggregatedFunction([legendre_builder.build(i), hermite_builder.build(i)])
    basis.append(f_i)

basis = ot.Basis(basis)