Compute the standard QTT-representation from the QTT-Tucker [TT]=QTTTUCKER_TO_LINQTT(TT, EPS) Computes the "linear" QTT representation from the QTT-TUCKER. This is a technical function: use the corresponding constructor of the QTT-Tucker class. TT-Toolbox 2.2, 2009-2012 This is TT Toolbox, written by Ivan Oseledets et al. Institute of Numerical Mathematics, Moscow, Russia webpage: http://spring.inm.ras.ru/osel For all questions, bugs and suggestions please mail ivan.oseledets@gmail.com ---------------------------
0001 function [tt] = qtttucker_to_linqtt(qt, eps) 0002 %Compute the standard QTT-representation from the QTT-Tucker 0003 % [TT]=QTTTUCKER_TO_LINQTT(TT, EPS) Computes the "linear" QTT 0004 % representation from the QTT-TUCKER. This is a technical function: use 0005 % the corresponding constructor of the QTT-Tucker class. 0006 % 0007 % 0008 % TT-Toolbox 2.2, 2009-2012 0009 % 0010 %This is TT Toolbox, written by Ivan Oseledets et al. 0011 %Institute of Numerical Mathematics, Moscow, Russia 0012 %webpage: http://spring.inm.ras.ru/osel 0013 % 0014 %For all questions, bugs and suggestions please mail 0015 %ivan.oseledets@gmail.com 0016 %--------------------------- 0017 0018 0019 dphys = qt.dphys; 0020 tuck = qt.tuck; 0021 core = qt.core; 0022 rc = core.r; 0023 rt = core.n; 0024 ns = cell(dphys,1); 0025 for i=1:dphys 0026 ns{i} = tuck{i}.n; 0027 end; 0028 0029 tt = []; % we will kron the chunks 0030 % tt = tt_tensor; 0031 % tt.d = sum(L); 0032 % tt.ps = ones(tt.d+1,1); 0033 % tt.n = zeros(tt.d,1); 0034 % tt.r = zeros(tt.d+1,1); 0035 0036 % Move the nonorth to the first factor 0037 for i=1:dphys 0038 [tuck{i},rv]=qr(tuck{i}, 'lr'); 0039 cr = core{i}; 0040 cr = permute(cr, [2,1,3]); 0041 cr = reshape(cr, rt(i), rc(i)*rc(i+1)); 0042 cr = rv*cr; 0043 rt(i) = size(rv, 1); 0044 cr = reshape(cr, rt(i), rc(i), rc(i+1)); 0045 core{i} = permute(cr, [2, 1, 3]); 0046 end; 0047 [core,nrm]=qr(core, 'rl'); 0048 cr = core{1}; 0049 cr = nrm*cr; 0050 core{1} = cr; 0051 rc = core.r; 0052 % cr = permute(cr, [1,3,2]); 0053 % cr = reshape(cr, rc(1)*rc(2), rt(1)); 0054 % [q,rv]=qr(cr, 0); 0055 % tuck{1} = tuck{1}*(rv.'); 0056 % rt(1) = size(q,2); 0057 % q = reshape(q, rc(1), rc(2), rt(1)); 0058 % core{1} = permute(q, [1, 3, 2]); 0059 0060 % Now, we can start to move the ranks to the linear model 0061 for i=1:dphys 0062 curtuck = tuck{i}; 0063 cr = core{i}; 0064 cr = permute(cr, [2, 1, 3]); 0065 cr = reshape(cr, rt(i), rc(i)*rc(i+1)); 0066 curtuck = curtuck*cr; % now the last rank is rc(i)*rc(i+1) 0067 curtuck = tt_reshape(curtuck, [ns{i}; rc(i); rc(i+1)], eps); 0068 % Now the most dangerous: the movement of the block rc(i) to the beginning 0069 curtuck = move_tt_block(curtuck, numel(ns{i})+1, 1, eps); 0070 curtuck = tt_reshape(curtuck, [rc(i)*ns{i}(1); ns{i}(2:end-1); ns{i}(end)*rc(i+1)], eps); 0071 % the data is in fact done; update the rank and n formally 0072 curtuck.r(1) = rc(i); 0073 curtuck.n(1) = ns{i}(1); 0074 curtuck.r(numel(ns{i})+1) = rc(i+1); 0075 curtuck.n(numel(ns{i})) = ns{i}(numel(ns{i})); 0076 % Ha-ha, that's not all; QR to the rest of the tucker core, so we will be able to proceed further 0077 if (i<dphys) 0078 [curtuck, rv]=qr(curtuck, 'lr'); 0079 cr2 = core{i+1}; 0080 cr2 = reshape(cr2, rc(i+1), rt(i+1)*rc(i+2)); 0081 cr2 = rv*cr2; 0082 rc(i+1) = size(rv, 1); 0083 core{i+1} = reshape(cr2, rc(i+1), rt(i+1), rc(i+2)); 0084 end; 0085 % Now, stuff to the TT 0086 tt = kron(tt, curtuck); 0087 end; 0088 0089 0090 end