tensor_methods

Tensor Methods for DS and SC
git clone git://popovic.xyz/tensor_methods.git
Log | Files | Refs

functions.jl (3756B)


      1 #/usr/bin/julia
      2 
      3 using LinearAlgebra
      4 
      5 @doc raw"""
      6     mode_k_dot(T, Z, k)
      7 
      8 Compute the mode-$k$ contraction of a tensor $S$ of size $n_1 ×  ⋯ × n_d$
      9 with a matrix $Z$ of size $r × n_k$
     10 
     11 Out: A tensor $S$ of size $n_1 ×  ⋯ ×  n_{k-1} ×  r ×  n_{k+1} ×  ⋯ × n_d$
     12 """
     13 function mode_k_dot(S, Z, k)
     14     n = size(S)
     15     r = size(Z)[1]
     16 
     17     if length(n) < k
     18         error("Try a smaller k")
     19     end
     20     if (size(Z))[2] != n[k]
     21         error("Z not of the correct size for mode-k contraction")
     22     end
     23 
     24     end_dim = [[n[i] for i in 1:(k-1)]..., r, [n[i] for i in (k+1):length(n)]...]
     25     alpha_dim = [n[i] for i in 1:length(n) if i!=k]
     26     T = []
     27     for alpha in 1:r
     28         s = zeros(alpha_dim...)
     29         for i_k in 1:n[k]
     30             s +=  Z[alpha, i_k] * selectdim(S, k, i_k)
     31         end
     32         append!(T, s)
     33     end
     34     return reshape(T, end_dim...)
     35 end
     36 
     37 @doc raw"""
     38     multiplication_tensor(n)
     39 
     40 Compute the multiplication tensor for the multiplication $T$ of two matrices $A$ and $B$
     41 of size \alpha $n × n$, satisfying the column major convention
     42 
     43         $C_k = ∑_{i, j}^{n^2} T_{ijk} ⋅ A_i ⋅ B_k$
     44 """
     45 function multiplication_tensor(n)
     46     T = zeros(Int, n^2, n^2, n^2)
     47     U = zeros(n^2, n^3)
     48     V = zeros(n^2, n^3)
     49     W = zeros(n^2, n^3)
     50 
     51     count = 1
     52     for m=1:n:n^2, l=1:n
     53         k = (l-1)+m
     54         for (i, j) in zip(collect(l:n:n^2), collect(m:m+n))
     55             T[i, j, k] = 1
     56             U[i, count] = 1
     57             V[j, count] = 1
     58             W[k, count] = 1
     59             count += 1
     60         end
     61     end
     62     return T, [U, V, W]
     63 end
     64 
     65 @doc raw"""
     66     cpd_eval(U_i)
     67 
     68 Evaluate a rank-r CPD of a tensor $S$ of size $n_1 × ⋯ × n_d$, given $d$
     69 matrices $U_i$ of the size $n_k × r$.
     70 
     71         $U_i = [U_1, … , U_d]$
     72 """
     73 function cpd_eval(U_i)
     74     reverse!(U_i)
     75     d = length(U_i)
     76     r = size(U_i[1])[2]
     77     n_d = [size(U_i[i])[1] for i in 1:d]
     78     s = zeros(n_d...)
     79 
     80     for alpha in 1:r
     81         k = kron(U_i[1][:, alpha], U_i[2][:, alpha])
     82         for i in 2:(d-1)
     83             k = kron(k, U_i[i+1][:, alpha])
     84         end
     85         s += reshape(k, n_d...)
     86     end
     87     return s
     88 end
     89 
     90 @doc raw"""
     91     cpd_multiply(A, B, U, V, W)
     92 
     93 Compute the matrix multiplication $A ⋅ B$ using the rank-$n^3$ CPD of the multiplication Tensor,
     94 without evaluating the tensor
     95 """
     96 function cpd_multiply(A, B, U, V, W)
     97     n = size(A)[1]
     98     r = size(U)[2]
     99     C = zeros(n, n)
    100     for k=1:n^2
    101         C[k] = sum(sum(A[i] * U[i, alpha] for i=1:n^2)
    102                     * sum(B[j] * V[j, alpha] for j=1:n^2)
    103                     * W[k, alpha] for alpha=1:r)
    104     end
    105     return C
    106 end
    107 
    108 @doc raw"""
    109     strassen_alg(A, B)
    110 
    111 Implementation of the Stranssens Algorithm for two matrices $A$ and $B$
    112 of the size $2 × 2$
    113 """
    114 function strassen_alg(A, B)
    115     if size(A) != (2, 2) || size(B) != (2, 2)
    116         error("Choose 2x2 Matrices")
    117     end
    118     C = zeros(2, 2)
    119     M_1 = (A[1] + A[4])*(B[1] + B[4])
    120     M_2 = (A[2] + A[4])*B[1]
    121     M_3 = A[1]*(B[3] - B[4])
    122     M_4 = A[4]*(B[2] - B[1])
    123     M_5 = (A[1] + A[3])*B[4]
    124     M_6 = (A[2] - A[1])*(B[1] + B[3])
    125     M_7 = (A[3] - A[4])*(B[2] + B[4])
    126 
    127     C[1] = M_1 + M_4 - M_5 + M_7
    128     C[2] = M_2 + M_4
    129     C[3] = M_3 + M_5
    130     C[4] = M_1 - M_2 + M_3 + M_6
    131     return C
    132 end
    133 @doc raw"""
    134     rank_7_CPD()
    135 
    136 Get the rank-7 CPD of the $2 × 2$ multiplication tensor
    137 (Strassens Algorithm)
    138 """
    139 function rank_7_CPD()
    140     U = [1 0 1 0 1 -1 0  # A_i placement in M_{ijk}
    141          0 1 0 0 0 1 0
    142          0 0 0 0 1 0 1
    143          1 1 0 1 0 0 -1];
    144 
    145     V = [1 1 0 -1 0 1 0   # B_j placement in M_{ijk}
    146          0 0 0 1 0 0 1
    147          0 0 1 0 0 1 0
    148          1 0 -1 0 1 0 1];
    149 
    150     W = [1 0 0 1 -1 0 1  # M_{ijk} placement in C_k
    151          0 1 0 1 0 0 0
    152          0 0 1 0 1 0 0
    153          1 -1 1 0 0 1 0];
    154 
    155     return U, V, W
    156 end