-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdev.jl
More file actions
104 lines (76 loc) · 2.32 KB
/
dev.jl
File metadata and controls
104 lines (76 loc) · 2.32 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using Combinatorics
using LinearAlgebra
using ArgCheck
function is_a_square_three_tensor(W::Array)
length(size(W)) == 3 && all(size(W) .== size(W)[1])
end
function naive_tensor(W::Array)
if is_a_square_three_tensor(W)
n = size(W)[1]
sum_tensor_diag(sigma,rho, W) = prod(W[i,sigma[i],rho[i]] for i = 1:n)
return sum(sum_tensor_diag(sigma,rho, W) for sigma in permutations(collect(1:n)) for rho in permutations(collect(1:n)))
else
error("tensor permanent implemented only for square 3-indices tensors")
end
end
function ryser_tensor(W::Array)
"""implements the tensor permanent according to Ryser's factorization
without using Gray factoring
corresponds to Eq. 21 of https://arxiv.org/abs/1410.7687"""
@argcheck is_a_square_three_tensor(W) "tensor permanent implemented only for square 3-indices tensors"
n = size(U)[1]
nstring = collect(1:n)
sub_nstring = collect(powerset(nstring))
sub_nstring = sub_nstring[2:length(sub_nstring)]
res = 0
function delta_set(S1, S2)
if S1 == S2
return 1
else
return 0
end
end
for r = 1:length(sub_nstring)
for s = r:length(sub_nstring)
R = sub_nstring[r]
S = sub_nstring[s]
t = prod(
sum(
W[rr,ss,j] for rr in R for ss in S
) for j = 1:n
)
res +=
(2 - delta_set(S, R)) * (-1)^(length(S) + length(R)) * real(t)
end
end
return res
end
function multi_dim_ryser(U, gram_matrix)
# https://arxiv.org/pdf/1410.7687.pdf
n = size(U)[1]
nstring = collect(1:n)
sub_nstring = collect(powerset(nstring))
sub_nstring = sub_nstring[2:length(sub_nstring)]
res = 0
function delta_set(S1, S2)
if S1 == S2
return 1
else
return 0
end
end
for r = 1:length(sub_nstring)
for s = r:length(sub_nstring)
R = sub_nstring[r]
S = sub_nstring[s]
t = prod(
sum(
U[ss, j] * conj(U[rr, j]) * gram_matrix[rr, ss] for rr in R for ss in S
) for j = 1:n
)
res +=
(2 - delta_set(S, R)) * (-1)^(length(S) + length(R)) * real(t)
end
end
return res
end