-
Notifications
You must be signed in to change notification settings - Fork 17
/
test_tenals.py
76 lines (71 loc) · 2.88 KB
/
test_tenals.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import unittest
import numpy as np
from scipy.linalg import qr
from gemelli.factorization import tenals
class Testtenals(unittest.TestCase):
def setUp(self):
# generate random noiseless low-rank orthogonal tensor
r = 3 # rank is 2
n1 = 10
n2 = 12
n3 = 8
U01 = np.random.rand(n1, r)
U02 = np.random.rand(n2, r)
U03 = np.random.rand(n3, r)
U1, temp = qr(U01)
U2, temp = qr(U02)
U3, temp = qr(U03)
U1 = U1[:, 0:r]
U2 = U2[:, 0:r]
U3 = U3[:, 0:r]
T = np.zeros((n1, n2, n3))
for i in range(n3):
T[:, :, i] = np.matmul(U1, np.matmul(np.diag(U3[i, :]), U2.T))
# sample entries
p = 2 * (r ** 0.5 * np.log(n1 * n2 * n3)) / np.sqrt(n1 * n2 * n3)
self.E = abs(np.ceil(np.random.rand(n1, n2, n3) - 1 + p))
self.TE = T * self.E
self.TE_noise = self.TE + (0.0001 / np.sqrt(n1 * n2 * n3)
* np.random.randn(n1, n2, n3) * self.E)
self.n3 = n3
self.U1 = U1
self.U2 = U2
self.U3 = U3
def test_tenals_noiseless(self):
# TenAls no noise
loadings, s, dist = tenals(self.TE, self.E)
L1, L2, L3 = loadings
s = np.diag(s)
# test accuracy
rmse = 0
for i3 in range(self.n3):
A1 = self.U1
A2 = np.matmul(self.U2, np.diag(self.U3[i3, :]))
B1 = L1
B2 = np.matmul(L2, np.diag(L3[i3, :] * s.T.flatten()))
rmse += np.trace(np.matmul(np.matmul(A1.T, A1), np.matmul(A2.T,
A2))) + \
np.trace(np.matmul(np.matmul(B1.T, B1), np.matmul(B2.T,
B2))) + \
-2 * np.trace(np.matmul(np.matmul(B1.T, A1), np.matmul(A2.T,
B2)))
self.assertTrue(1e2 > abs(rmse))
def test_tenals_noise(self):
# TenAls no noise
loadings, s, dist = tenals(self.TE_noise, self.E)
L1, L2, L3 = loadings
s = np.diag(s)
# test accuracy
rmse = 0
for i3 in range(self.n3):
A1 = self.U1
A2 = np.matmul(self.U2, np.diag(self.U3[i3, :]))
B1 = L1
B2 = np.matmul(L2, np.diag(L3[i3, :] * s.T.flatten()))
rmse += np.trace(np.matmul(np.matmul(A1.T, A1), np.matmul(A2.T,
A2))) + \
np.trace(np.matmul(np.matmul(B1.T, B1), np.matmul(B2.T,
B2))) + \
-2 * np.trace(np.matmul(np.matmul(B1.T, A1), np.matmul(A2.T,
B2)))
self.assertTrue(1e2 > abs(rmse))