Dot product of two QTT-Tuckers [PR]=DOT(TT1,TT2) -- dot product of two TT-tensors [PR]=DOT(TT1,TT2, DO_QR) if DO_QR==true is specified, perform the left-to-right QRs of TT1,TT2 before the scalar product. It increases the accuracy in some cases. In general, returns a 4D tensor of sizes r0(tt1), r0(tt2), rd(tt1), rd(tt2) If r0(tt1) = r0(tt2) = 1 it returns a matrix of size rd(tt1) x rd(tt2) 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 [p] = dot(qt1,qt2, do_qr) 0002 %Dot product of two QTT-Tuckers 0003 % [PR]=DOT(TT1,TT2) -- dot product of two TT-tensors 0004 % 0005 % [PR]=DOT(TT1,TT2, DO_QR) if DO_QR==true is specified, perform the 0006 % left-to-right QRs of TT1,TT2 0007 % before the scalar product. It increases the accuracy in some cases. 0008 % 0009 % In general, returns a 4D tensor of sizes 0010 % r0(tt1), r0(tt2), rd(tt1), rd(tt2) 0011 % If r0(tt1) = r0(tt2) = 1 it returns a matrix of size rd(tt1) x rd(tt2) 0012 % 0013 % 0014 % TT-Toolbox 2.2, 2009-2012 0015 % 0016 %This is TT Toolbox, written by Ivan Oseledets et al. 0017 %Institute of Numerical Mathematics, Moscow, Russia 0018 %webpage: http://spring.inm.ras.ru/osel 0019 % 0020 %For all questions, bugs and suggestions please mail 0021 %ivan.oseledets@gmail.com 0022 %--------------------------- 0023 0024 0025 if (nargin<3)||(isempty(do_qr)) 0026 do_qr = false; 0027 end; 0028 0029 d=qt1.dphys; 0030 for i=1:d 0031 % dot product of factors gives rt1 times rt2 matrix, to be convolved 0032 % between cores 0033 % Make it more precise by QRs? <-- already inside @tt_tensor/dot 0034 % [qt1.tuck{i}, rv1]=qr(qt1.tuck{i}, 'lr'); 0035 % [qt2.tuck{i}, rv2]=qr(qt2.tuck{i}, 'lr'); 0036 % rv1 = eye(qt1.tuck{i}.r(end)); 0037 % rv2 = eye(qt2.tuck{i}.r(end)); 0038 Pfac = squeeze(dot(qt1.tuck{i}, qt2.tuck{i}, do_qr)); % size rt1,rt2 0039 % rt1 = size(rv1, 2); rt2 = size(rv2, 2); 0040 % rt1new = size(rv1,1); rt2new = size(rv2,1); 0041 % Now, merge Pfac to the core of qt1 0042 curcr = qt2.core{i}; 0043 rc1 = size(curcr, 1); rt2 = size(curcr, 2); rc2 = size(curcr, 3); 0044 curcr = permute(curcr, [1, 3, 2]); 0045 curcr = reshape(curcr, rc1*rc2, rt2); 0046 % curcr = curcr*(rv1.'); 0047 curcr = curcr*(Pfac.'); % Now, core2 has the tucker ranks of qt1 0048 curcr = reshape(curcr, rc1, rc2, qt1.core.n(i)); 0049 qt2.core{i} = permute(curcr, [1, 3, 2]); 0050 0051 % curcr = qt2.core{i}; 0052 % rc1 = size(curcr, 1); rc2 = size(curcr, 3); 0053 % curcr = permute(curcr, [1, 3, 2]); 0054 % curcr = reshape(curcr, rc1*rc2, rt2); 0055 % curcr = curcr*(rv2.'); 0056 % curcr = reshape(curcr, rc1, rc2, rt2new); 0057 % qt2.core{i} = permute(curcr, [1, 3, 2]); 0058 end; 0059 % Finaly, dot product of cores. It is consistent, since we merged Pfacs 0060 p = dot(qt1.core, qt2.core, do_qr); 0061 end