Module func_full: Functional full format including Chebyshev interpolation

Package teneva, module func_full: functional full format with interpolation.

This module contains the functions for construction of the functional representation in the full format with Chebyshev interpolation, as well as calculating the values of the function using the constructed interpolation coefficients. See module “func” with the same functions in the TT-format. The functions presented in this module are especially relevant for the one-dimensional (and two-dimensional) case, when the TT-decomposition cannot be applied.




teneva.func_full.func_get_full(X, A, a, b, z=0.0, skip_out=True)[source]

Compute the Chebyshev approximation in given points (approx. f(X)).

Parameters:
  • X (np.ndarray) – spatial points of interest (it is 2D array of the shape [samples, d], where d is the number of dimensions).

  • A (list) – TT-tensor of the interpolation coefficients (it has d dimensions).

  • a (float, list, np.ndarray) – grid lower bounds for each dimension (list or np.ndarray of length d). It may be also float, then the lower bounds for each dimension will be the same.

  • b (float, list, np.ndarray) – grid upper bounds for each dimension (list or np.ndarray of length d). It may be also float, then the upper bounds for each dimension will be the same.

  • z (float) – the value for points, which are outside the spatial grid.

  • skip_out (bool) – if flag is set, then the values outside the spatial grid will be set to z values.

Returns:

approximated function values in X points (it is 1D array of the shape [samples]).

Return type:

np.ndarray

Note

See also the same function (“func_get”) in the TT-format.

Examples:

# In the beginning we compute the function values on the Chebyshev grid:
from scipy.optimize import rosen
f = lambda X: rosen(X.T) # Target function

a = [-2., -4., -3., -2.] # Grid lower bounds
b = [+2., +3., +4., +2.] # Grid upper bounds
n = [5, 6, 7, 8]         # Grid size
I = teneva.grid_flat(n)
X = teneva.ind_to_poi(I, a, b, n, 'cheb')
Y = f(X).reshape(n, order='F')
print(Y.shape)

# >>> ----------------------------------------
# >>> Output:

# (5, 6, 7, 8)
#
# Then we should compute the array for Chebyshev interpolation coefficients:
A = teneva.func_int_full(Y)

print(A.shape)

# >>> ----------------------------------------
# >>> Output:

# (5, 6, 7, 8)
#
# Finally we compute the approximation in selected points inside the bounds:
# (the values for points outside the bounds will be set as "z")
X = np.array([
    [0., 0., 0., 0.],
    [0., 2., 3., 2.],
    [1., 1., 1., 1.],
    [1., 1., 1., 99999999],
])

Z = teneva.func_get_full(X, A, a, b, z=-1.)

print(Z)       # Print the result
print(f(X))    # We can check the result by comparing it to the true values

# >>> ----------------------------------------
# >>> Output:

# [ 3.00000000e+00  5.40600000e+03  3.86535248e-12 -1.00000000e+00]
# [3.0000000e+00 5.4060000e+03 0.0000000e+00 9.9999996e+17]
#


teneva.func_full.func_gets_full(A, a, b, m=None)[source]

Compute the Chebyshev approximation all over the new grid.

Parameters:
  • A (np.ndarray) – d-dimensional tensor of the interpolation coefficients.

  • a (float, list, np.ndarray) – grid lower bounds for each dimension (list or np.ndarray of length d). It may be also float, then the lower bounds for each dimension will be the same.

  • b (float, list, np.ndarray) – grid upper bounds for each dimension (list or np.ndarray of length d). It may be also float, then the upper bounds for each dimension will be the same.

  • m (int, float, list, np.ndarray) – tensor size for each dimension of the new grid (list or np.ndarray of length d). It may be also int/float, then the size for each dimension will be the same. If it is not set, then original grid size (from the interpolation) will be used.

Returns:

array of the approximated function values on the full new grid. This is the d-dimensional array of the shape m.

Return type:

np.ndarray

Note

This function is not efficient in the full format, and corresponds to a simple explicit calculation of all values at the nodes of the new grid. At the same time, in the TT-format (“func_gets”), the corresponding operation is carried out in an implicit efficient form. Accordingly, this function is provided only for uniformity of presentation.

Examples:

# In the beginning we compute the function values on the Chebyshev grid:
from scipy.optimize import rosen
f = lambda X: rosen(X.T) # Target function

a = [-2., -4., -3., -2.] # Grid lower bounds
b = [+2., +3., +4., +2.] # Grid upper bounds
n = [5, 6, 7, 8]         # Grid size
I = teneva.grid_flat(n)
X = teneva.ind_to_poi(I, a, b, n, 'cheb')
Y = f(X).reshape(n, order='F')
print(Y.shape)

# >>> ----------------------------------------
# >>> Output:

# (5, 6, 7, 8)
#
# Then we should compute the array for Chebyshev interpolation coefficients:
A = teneva.func_int_full(Y)

print(A.shape)

# >>> ----------------------------------------
# >>> Output:

# (5, 6, 7, 8)
#
m = [7, 8, 9, 10] # New size of the grid

# Compute tensor on finer grid:
Z = teneva.func_gets_full(A, a, b, m)

print(Z.shape)

# >>> ----------------------------------------
# >>> Output:

# (7, 8, 9, 10)
#
# We can compute interpolation coefficients on the new grid:
B = teneva.func_int_full(Z)

print(B.shape)

# >>> ----------------------------------------
# >>> Output:

# (7, 8, 9, 10)
#
# Finally we compute the approximation in selected points inside
# the bounds for 2 different approximations:
X = np.array([
    [0., 0., 0., 0.],
    [0., 2., 3., 2.],
    [1., 1., 1., 1.],
    [1., 1., 1., 99999999],
])

z1 = teneva.func_get_full(X, A, a, b, z=-1.)
z2 = teneva.func_get_full(X, B, a, b, z=-1.)

# We can check the result by comparing it to the true values:
print(z1)
print(z2)
print(f(X))

# >>> ----------------------------------------
# >>> Output:

# [ 3.00000000e+00  5.40600000e+03  3.86535248e-12 -1.00000000e+00]
# [ 3.00000000e+00  5.40600000e+03  2.18847163e-12 -1.00000000e+00]
# [3.0000000e+00 5.4060000e+03 0.0000000e+00 9.9999996e+17]
#


teneva.func_full.func_int_full(Y)[source]

Compute the tensor for Chebyshev interpolation coefficients.

Parameters:

Y (np.ndarray) – d-dimensional array with function values on the Chebyshev grid.

Returns:

array that collects interpolation coefficients. It has the same shape as the given tensor Y.

Return type:

np.ndarray

Note

See also the same function (“func_int”) in the TT-format.

Examples:

# In the beginning we compute the function values on the Chebyshev grid:
from scipy.optimize import rosen
f = lambda X: rosen(X.T) # Target function

a = [-2., -4., -3., -2.] # Grid lower bounds
b = [+2., +3., +4., +2.] # Grid upper bounds
n = [5, 6, 7, 8]         # Grid size
I = teneva.grid_flat(n)
X = teneva.ind_to_poi(I, a, b, n, 'cheb')
Y = f(X).reshape(n, order='F')
print(Y.shape)

# >>> ----------------------------------------
# >>> Output:

# (5, 6, 7, 8)
#
# Then we can compute the array for Chebyshev interpolation coefficients:
A = teneva.func_int_full(Y)

print(A.shape)

# >>> ----------------------------------------
# >>> Output:

# (5, 6, 7, 8)
#


teneva.func_full.func_sum_full(A, a, b)[source]

Integrate the function from its Chebyshev approximation.

Parameters:
  • A (np.ndarray) – d-dimensional tensor of the interpolation coefficients.

  • a (float, list, np.ndarray) – grid lower bounds for each dimension (list or np.ndarray of length d). It may be also float, then the lower bounds for each dimension will be the same.

  • b (float, list, np.ndarray) – grid upper bounds for each dimension (list or np.ndarray of length d). It may be also float, then the upper bounds for each dimension will be the same.

Returns:

the value of the integral.

Return type:

float

Note

This function works only for symmetric grids! See also the same function (“func_sum”) in the TT-format.

Examples:

# In the beginning we compute the function values on the Chebyshev grid:

d = 4
def f(X): # Target function
    a = 2.
    r = np.exp(-np.sum(X*X, axis=1) / a) / (np.pi * a)**(d/2)
    return r.reshape(-1)

a = [-12., -14., -13., -11.] # Grid lower bounds
b = [+12., +14., +13., +11.] # Grid upper bounds
n = [50, 50, 50, 50]         # Grid size
I = teneva.grid_flat(n)
X = teneva.ind_to_poi(I, a, b, n, 'cheb')
Y = f(X).reshape(n, order='F')
print(Y.shape)

# >>> ----------------------------------------
# >>> Output:

# (50, 50, 50, 50)
#
# Then we should compute the array for Chebyshev interpolation coefficients:
A = teneva.func_int_full(Y)

print(A.shape)

# >>> ----------------------------------------
# >>> Output:

# (50, 50, 50, 50)
#
# Finally we compute the integral:
v = teneva.func_sum_full(A, a, b)

print(v)       # Print the result (the real value is 1.)

# >>> ----------------------------------------
# >>> Output:

# 1.0000000191598715
#