One right-to-left sweep of the TT-cross method. [TT,IND_RIGHT]=TT_CROSSR(D,N,FUN,IND_LEFT) Computes one QR-maxvol sweep of the TT-cross method. The input is the pair (D,N) that determines the size of the tensor, FUN is the function handle to evaluate a particular element of the tensor, i.e., VAL=FUN(IND). To pass parameters, please use anonymous function handles in MATLAB. 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,ind_right]=tt_crossr(arr,ind_left) 0002 %One right-to-left sweep of the TT-cross method. 0003 % [TT,IND_RIGHT]=TT_CROSSR(D,N,FUN,IND_LEFT) Computes one QR-maxvol sweep 0004 % of the TT-cross method. The input is the pair (D,N) that determines the 0005 % size of the tensor, FUN is the function handle to evaluate a particular 0006 % element of the tensor, i.e., VAL=FUN(IND). To pass parameters, please 0007 % use anonymous function handles in MATLAB. 0008 % 0009 % 0010 % 0011 % TT-Toolbox 2.2, 2009-2012 0012 % 0013 %This is TT Toolbox, written by Ivan Oseledets et al. 0014 %Institute of Numerical Mathematics, Moscow, Russia 0015 %webpage: http://spring.inm.ras.ru/osel 0016 % 0017 %For all questions, bugs and suggestions please mail 0018 %ivan.oseledets@gmail.com 0019 %--------------------------- 0020 0021 d=arr{1}; 0022 sz=arr{2}; 0023 %arr1=arr(:); 0024 tt=cell(d,1); 0025 ind_right=cell(d,1); %Computed ind_right 0026 ind_l=ind_left{d-1}; 0027 r1=size(ind_l,2); 0028 ncur=sz(1); 0029 mat=zeros(ncur,r1); 0030 for j=1:ncur 0031 for s=1:r1 0032 ind_f=[ind_l(:,s)',j]; 0033 %mat(j,s)=arr1(sub_to_ind(ind_f,sz)); 0034 val=my_elem(ind_f,arr); 0035 mat(j,s)=val; 0036 end 0037 end 0038 [qs,rs]=qr(mat,0); 0039 ind=maxvol2(qs); 0040 ind_right{d-1}=ind; 0041 %mat=mat*inv(mat(ind,:)); 0042 mat=qs*inv(qs(ind,:)); 0043 tt{d}=mat; 0044 0045 for k=(d-1):-1:2 0046 ncur=sz(k); 0047 ind_l=ind_left{k-1}; 0048 ind_r=ind_right{k}; 0049 r2=size(ind_l,2); 0050 r3=size(ind_r,2); 0051 core=zeros(ncur,r2,r3); 0052 %fprintf('k=%d \n'); 0053 for i=1:ncur 0054 for s2=1:r2 0055 for s3=1:r3 0056 ind_f=[ind_l(:,s2)',i,ind_r(:,s3)']; 0057 val=my_elem(ind_f,arr); 0058 core(i,s2,s3)=val; 0059 %core(i,s2,s3)=arr1(sub_to_ind(ind_f,sz)); 0060 0061 end 0062 end 0063 end 0064 %core is ncurxr2xr3, from the left we need 0065 %r2xncurxr3, but from the right 0066 %we need (ncurxr3)xr2 or (r3xncur)xr2 0067 core=permute(core,[3,1,2]); core=reshape(core,[r3*ncur,r2]); 0068 rnew=min(r2,r3*ncur); 0069 [qs,rs]=qr(core,0); 0070 ind=maxvol2(qs); 0071 ind_old=ind_right{k}; 0072 ind_new=zeros(d-k+1,rnew); 0073 ncur=sz(k); 0074 for s=1:rnew 0075 f_in=ind(s); 0076 w1=tt_ind2sub([r3,ncur],f_in); 0077 rs=w1(1); js=w1(2); 0078 ind_new(:,s)=[js,ind_old(:,rs)']; 0079 end 0080 ind_right{k-1}=ind_new; 0081 %core=core*inv(core(ind,:)); 0082 core=qs*inv(qs(ind,:)); 0083 0084 % core=reshape(core,[r2,ncur,r3]); core=permute(core,[2,1,3]); 0085 % core=reshape(core,[ncur,r3,r2]); core=permute(core,[1,3,2]); 0086 core=reshape(core,[r3,ncur,rnew]); core=permute(core,[2,3,1]); 0087 0088 tt{k}=core; 0089 end 0090 ncur=sz(1); 0091 ind_r=ind_right{1}; 0092 r=size(ind_r,2); 0093 mat=zeros(ncur,r); 0094 for i=1:ncur 0095 for s=1:r 0096 ind_f=[i,ind_r(:,s)']; 0097 val=my_elem(ind_f,arr); 0098 mat(i,s)=val; 0099 %mat(i,s)=arr1(sub_to_ind(ind_f,sz)); 0100 end 0101 end 0102 tt{1}=mat; 0103 %for k=1:d 0104 % res=tt{k}-tt_true{k}; 0105 % res=res(:); 0106 % fprintf('k=%d, approximation error: %e \n',k,norm(res)); 0107 %end 0108 return 0109 end