DPG demo version from 2019-08-20
[dpg] / tensor / trefold.m
1 function result = trefold(tmp,sz,d)
2 %
3 % TREFOLD - tensor re-fold
4 %           expands the dimension of a tensor by "refolding" along one direction
5 %          (un-does the unfolding as described by deLathauwer in SIMAX 21(4):1253)
6 %
7 % Usage: A = trefold(unfA,sz,d)
8 %
9 % Example: given a 3D tensor, A, 
10 %
11 % unfold(A,2) =>        I1
12 %                     +----+ +----+ +----+
13 %                  I2 |    | |    | |    |
14 %                     |    | |    | |    |
15 %                     +----+ +----+ +----+
16 %                        \ ____|____ /
17 %                              I3
18 %
19 % for a 3D tensor, 
20 %
21 % unfold(A,1) =  [ A(:,1,:)  A(:,2,:)  ... A(:,n2,:)  ],
22 % unfold(A,2) = ( A(:,:,1)' A(:,:,2)' ... A(:,:,n3)' ),
23 % unfold(A,3) = ( A(1,:,:)' A(2,:,:)' ... A(n1,:,:)' )
24 %
25 % To fold the matrix back (i.e. undo the unfold), one *must* know the
26 % size of the final matrix and use the same permutation as the unfolding.  
27 % An example:
28 %    sz = size(A);
29 %    A == permute( reshape( unfold(A,d) , sz([ d:-1:1 N:-1:(d+1) ]) ), ...
30 %                  [  d:-1:1 N:-1:(d+1) ] );
31 %
32
33 %
34 % Copyright 2008  W. Scott Hoge  (wsh032580 at proton dot me)
35 %
36 % Licensed under the terms of the MIT License 
37 % (https://opensource.org/licenses/MIT)
38
39 % sz = size(A);
40 N = length(sz);
41 if (d > length(sz)), result = A; return; end;
42
43 result = permute( reshape( tmp, sz( [ d:-1:1 N:-1:(d+1) ] ) ), ...
44                   [ d:-1:1 N:-1:(d+1) ] );
45
46
47 % unfold(A,1) = reshape( permute( A, [ 1 3 2 ]), [sz(1) prod(sz(3:2)) ] )
48 % unfold(A,2) = reshape( permute( A, [ 2 1 3 ]), [sz(2) prod(sz([1 3])) ] )
49 % unfold(A,3) = reshape( permute( A, [ 3 2 1 ]), [sz(3) prod(sz([1 2])) ] )
50