Module core: operations with individual TT-cores

Package teneva, module core: operations with individual TT-cores.

This module contains functions to work directly with individual TT-cores.




teneva.core.core_qtt_to_tt(Q_list)[source]

Transform the list of QTT-cores into a TT-core.

Parameters:

Q_list (list of np.ndarray) – list of QTT-cores of the shapes [[q_0, 2, q_1], [q_1, 2, q_2], …[q_(q-1), 2, q_q]] and length q.

Returns:

TT-core in the form of 3-dimensional array of the shape q_0 x 2^q x q_q.

Return type:

np.ndarray

Examples:

# TT-ranks for cores:
r_list = [4, 3, 5, 8, 18, 2, 4, 3]

# Create random QTT-cores:
Q_list = []
for i in range(1, len(r_list)):
    Q = np.random.randn(r_list[i-1], 2, r_list[i])
    Q_list.append(Q)

# Transform the QTT-cores into one TT-core:
G = teneva.core_qtt_to_tt(Q_list)

print(f'Shape : {G.shape}')

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

# Shape : (4, 128, 3)
#


teneva.core.core_stab(G, p0=0, thr=1e-100)[source]

Scaling for the passed TT-core, i.e., G -> (Q, p), G = 2^p * Q.

Parameters:
  • G (np.ndarray) – TT-core in the form of 3-dimensional array.

  • p0 (int) – optional initial value of the power-factor (it will be added to returned value p).

  • thr (float) – threshold value for applying scaling (if the maximum modulo element in the TT-core is less than this value, then scaling will not be performed).

Returns:

scaled TT-core (Q) and power-factor (p), such that G = 2^p * Q.

Return type:

(np.ndarray, int)

Examples:

r = 4   # Left TT-rank
n = 10  # Mode size
q = 5   # Right TT-rank

# Create random TT-core:
G = np.random.randn(r, n, q)

# Perform scaling:
Q, p = teneva.core_stab(G)

print(p)
print(np.max(np.abs(Q)))
print(np.max(np.abs(G - 2**p * Q)))

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

# 1
# 1.3484433214707858
# 0.0
#

For convenience, we can set an initial value for the power-factor:

p0 = 2
Q, p = teneva.core_stab(G, p0)

print(p)
print(np.max(np.abs(Q)))
print(np.max(np.abs(G - 2**(p-p0) * Q)))

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

# 3
# 1.3484433214707858
# 0.0
#


teneva.core.core_tt_to_qtt(G, e=0.0, r=1000000000000.0)[source]

Transform the TT-core into a list of QTT-cores.

Parameters:
  • G (np.ndarray) – TT-core in the form of 3-dimensional array of the shape r1xnxr2. The mode size should be a power of two, i.e., n=2^d.

  • e (float) – desired approximation accuracy.

  • r (int) – maximum rank for the SVD decomposition.

Returns:

list of QTT-cores (np.ndarrays) of the shape [q1, 2, q2], which approximates the given TT-core G.

Return type:

list

Examples:

r = 3      # Left TT-rank
n = 2**10  # Mode size
q = 5      # Right TT-rank

# Create random TT-core:
G = np.random.randn(r, n, q)

# Transform the core to QTT:
Q_list = teneva.core_tt_to_qtt(G)

print('Len  : ', len(Q_list))
print('Q  1 : ', Q_list[0].shape)
print('Q  2 : ', Q_list[1].shape)
print('Q 10 : ', Q_list[-1].shape)

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

# Len  :  10
# Q  1 :  (3, 2, 6)
# Q  2 :  (6, 2, 12)
# Q 10 :  (10, 2, 5)
#

We can check the result if transform the list of the QTT-cores back:

G_new = teneva.core_qtt_to_tt(Q_list)

eps = np.max(np.abs(G_new - G))

print(f'Shape : {G_new.shape}')
print(f'Eps   : {eps:-7.1e}')

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

# Shape : (3, 1024, 5)
# Eps   : 2.0e-14
#