Home > tt2 > @tt_tensor > funcrs2.m

funcrs2

PURPOSE ^

Cross approximation of a function of a TT-tensor, Method 2

SYNOPSIS ^

function [y]=funcrs2(tt,fun,eps,y,nswp)

DESCRIPTION ^

Cross approximation of a function of a TT-tensor, Method 2
   [Y]=FUNCRS2(TT,FUN,EPS,Y,NSWP)
   Computes approximation to the function FUN(TT) with accuracy EPS
   Auxiliary parameters:  Y (initial approximation), NSWP
   (number of sweeps in the method
   Much faster then usual cross by vectorized computation of subtensors


 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
---------------------------

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [y]=funcrs2(tt,fun,eps,y,nswp)
0002 %Cross approximation of a function of a TT-tensor, Method 2
0003 %   [Y]=FUNCRS2(TT,FUN,EPS,Y,NSWP)
0004 %   Computes approximation to the function FUN(TT) with accuracy EPS
0005 %   Auxiliary parameters:  Y (initial approximation), NSWP
0006 %   (number of sweeps in the method
0007 %   Much faster then usual cross by vectorized computation of subtensors
0008 %
0009 %
0010 % TT-Toolbox 2.2, 2009-2012
0011 %
0012 %This is TT Toolbox, written by Ivan Oseledets et al.
0013 %Institute of Numerical Mathematics, Moscow, Russia
0014 %webpage: http://spring.inm.ras.ru/osel
0015 %
0016 %For all questions, bugs and suggestions please mail
0017 %ivan.oseledets@gmail.com
0018 %---------------------------
0019 
0020 
0021 %PARAMETERS SECTION
0022 rmin=1;
0023 verb=true;
0024 kick_rank=5;
0025 if (~isempty(y))
0026    yold=y;
0027 end
0028 y1=y;
0029 %For this procedure we need only local (!) indices, since it
0030 %is more or less equivalent to orthogonalization;
0031 d=tt.d;
0032 ps=tt.ps;
0033 core0=tt.core;
0034 n=tt.n;
0035 r=tt.r;
0036 
0037 ry=y.r;
0038 psy=y.ps;
0039 cry=y.core;
0040 phi=cell(d+1,1);
0041 phi{d+1}=1;
0042 phi{1}=1;
0043 phx=cell(d+1,1);
0044 phx{d+1}=1; %For storing submatrices in U & V
0045 phx{1}=1;
0046 %Warmup procedure: orthogonalize from right-to-left & maxvol
0047    cry_old=cry; %This is for checking the accuracy
0048    psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0049    pos1=psy(d+1);
0050    %The first is the the o
0051    for i=d-1:-1:1
0052       %Do right-to-left SVD + maxvol (i.e., no fun() is employed, just the
0053       %current approximation)
0054       cr=cry(pos1-ry(i+1)*n(i+1)*ry(i+2):pos1-1);
0055       cr2=cry_old(psy(i):psy(i+1)-1);
0056       cr2=reshape(cr2,[ry(i)*n(i),ry(i+1)]);
0057       cr=reshape(cr,[ry(i+1),n(i+1)*ry(i+2)]);
0058       %cr=cr.';
0059       %[cr,rm]=qr(cr,0);
0060       %rm=2*eye(ry(i+1));
0061       %cr=cr/2;
0062       [u,s,v]=svd(cr,'econ'); s=diag(s);
0063       ry(i+1) = my_chop2(s,norm(s)*eps/sqrt(d-1));
0064       %cr = u * s * v', I think we should leave v orthogonal
0065       u=u(:,1:ry(i+1)); v=v(:,1:ry(i+1));
0066       s=s(1:ry(i+1)); u=u*diag(s);
0067       cr=conj(v); %cr is n(i+1),ry(i+2),ry(i+1) ---  No. it is conj(v)
0068       rm=u.'; %This is discussable --- maybe u' (or u.')?
0069       ry(i+1)=size(cr,2);
0070       %Maxvol should be computed in a different matrix
0071       cr0=reshape(cr,[n(i+1),ry(i+2),ry(i+1)]);
0072       cr0=permute(cr0,[3,1,2]);
0073       cr0=reshape(cr0,[ry(i+1)*n(i+1),ry(i+2)]);
0074       cr0=cr0*phx{i+2}.';
0075       cr0=reshape(cr0,[ry(i+1),n(i+1)*ry(i+2)]);
0076       cr0=cr0.';
0077       ind=maxvol2(cr0);
0078       r1=cr0(ind,:);
0079       phx{i+1}=r1;
0080 
0081       cr=cr.';
0082 
0083       cry(pos1-ry(i+1)*n(i+1)*ry(i+2):pos1-1)=cr(:);
0084       pos1=pos1-ry(i+1)*n(i+1)*ry(i+2);
0085       cr2=cr2*(rm).';
0086       cry(pos1-ry(i)*n(i)*ry(i+1):pos1-1)=cr2(:);
0087       %Take phi matrix; convolve from right with current cors of V
0088       cr0=core0(ps(i+1):ps(i+2)-1);
0089       cr0=reshape(cr0,[r(i+1)*n(i+1),r(i+2)]);
0090       cr0=cr0*phi{i+2}; %cr0 is now r(i)*n(i)*ry(i+1);
0091       cr0=reshape(cr0,[r(i+1),n(i+1)*ry(i+2)]);
0092       phi{i+1}=cr0(:,ind);
0093    end
0094    pos1=pos1-ry(1)*n(1)*ry(2);
0095    psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0096    cry=cry(pos1:numel(cry));
0097    y.core=cry;
0098    y.r=ry;
0099    y.ps=psy;
0100 
0101    swp=1;
0102 yold=[];
0103 not_converged = true;
0104 while ( swp < nswp && not_converged )
0105     max_er=0;
0106 cry_old=cry; %This is for checking the accuracy
0107 psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0108 pos1=1;
0109  for i=1:d-1
0110      %fprintf('i=%d \n',i);
0111      %We care for two cores, with number i & number i+1, and use
0112      %psi(i) and psi(i+2) as a basis; also we will need to recompute
0113      %psi(i+1)
0114      ps1=phi{i}; ps2=phi{i+2}; px1=phx{i}; px2=phx{i+2};
0115      %Compute (!) superblock and function (!) of it
0116      cr1=core0(ps(i):ps(i+1)-1);
0117      cr2=core0(ps(i+1):ps(i+2)-1);
0118      cr1=reshape(cr1,[r(i),n(i)*r(i+1)]);
0119      cr1=ps1*cr1;
0120      cr2=reshape(cr2,[r(i+1)*n(i+1),r(i+2)]);
0121      cr2=cr2*ps2;
0122      cr1=reshape(cr1,[ry(i)*n(i),r(i+1)]);
0123      cr2=reshape(cr2,[r(i+1),n(i+1)*ry(i+2)]);
0124      cr=cr1*cr2;
0125      %cr=reshape(cr,[ry(i)*n(i)*n(i+1),ry(i+2)]);
0126      cr=fun(cr); %Elements are evaluated here!
0127      cr=reshape(cr,[ry(i)*n(i)*n(i+1),ry(i+2)]);
0128      cr = cr/(px2.');
0129      cr=reshape(cr,[ry(i),n(i)*n(i+1)*ry(i+2)]);
0130      cr=px1 \cr;
0131      cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0132      %Check for local approximation of cr for the error
0133      cry1=cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1);
0134      %cry2=cry(pos1+ry(i)*n(i)*ry(i+1):pos1+ry(i)*n(i)*ry(i+1)+ry(i+1)*n(i+1)*ry(i+2)-1);
0135      %if ( swp == 2 )
0136      % if ( i == 5 )
0137      %   keyboard;
0138      % end
0139      %end
0140      cry2=cry_old(psy(i+1):psy(i+2)-1);
0141 
0142      cry1=reshape(cry1,[ry(i)*n(i),ry(i+1)]);
0143      cry2=reshape(cry2,[ry(i+1),n(i+1)*ry(i+2)]);
0144      appr=cry1*cry2;
0145      er=norm(appr-cr,'fro')/norm(cr,'fro');
0146      %keyboard;
0147      max_er=max(er,max_er);
0148 
0149      %Compute SVD of cr
0150 
0151      [u,s,v]=svd(cr,'econ');
0152      s=diag(s);
0153      r2=my_chop2(s,eps*norm(s)/sqrt(d-1));
0154      s=s(1:r2); u=u(:,1:r2); v=v(:,1:r2);
0155      v=v*diag(s);
0156 
0157      %Kick rank of u
0158      ur=randn(size(u,1),kick_rank);
0159      %Orthogonalize ur to u by Golub-Kahan reorth
0160      u=reort(u,ur);
0161      radd=size(u,2)-r2;
0162      if ( radd > 0 )
0163        vr=zeros(size(v,1),radd);
0164        v=[v,vr];
0165      end
0166      r2=size(u,2);
0167 
0168 
0169      %ind=maxvol2(u);
0170      %r1=u(ind,:);
0171      %u=u/r1; v=v*r1'; v=v.';
0172      v=v.';
0173      ry(i+1)=r2;
0174      cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1)=u(:);
0175      pos1=pos1+ry(i)*n(i)*ry(i+1);
0176      cry(pos1:pos1+ry(i+1)*n(i+1)*ry(i+2)-1)=v(:);
0177 
0178 
0179 
0180      %Compute new maxvol and (new) submatrices
0181      u=reshape(u,[ry(i),n(i)*ry(i+1)]);
0182      u=px1*u;
0183      u=reshape(u,[ry(i)*n(i),ry(i+1)]);
0184      ind=maxvol2(u);
0185      phx{i+1}=u(ind,:);
0186      %Now we have to: cr1 with phi from the left
0187      phi{i+1}=cr1(ind,:); %phi{i+1}=phi{i+1};
0188 
0189 
0190  end
0191   %Truncate local memory
0192   cry=cry(1:pos1+ry(d)*n(d)*ry(d+1)-1);
0193   psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0194 y.core=cry;
0195 y.r=ry;
0196 y.ps=psy;
0197 cry_old=cry;
0198 %m=numel(cry);
0199 %cry=[zeros(size(cry)),cry];
0200 %pos1=pos1+m;
0201 %cry2=cry_old(psy(i+1):psy(i+2)-1);
0202 cry=cry(psy(d):psy(d+1)-1); %Start--only two cores
0203  for i=d-1:-1:1
0204      %fprintf('i=%d \n',i);
0205      %We care for two cores, with number i & number i+1, and use
0206      %psi(i) and psi(i+2) as a basis; also we will need to recompute
0207      %psi(i+1)
0208      ps1=phi{i}; ps2=phi{i+2}; px1=phx{i}; px2=phx{i+2};
0209      %Take current core; convolve it with
0210      %core=core(ps
0211      %Compute (!) superblock and function (!) of it
0212      cr1=core0(ps(i):ps(i+1)-1);
0213      cr2=core0(ps(i+1):ps(i+2)-1);
0214      cr1=reshape(cr1,[r(i),n(i)*r(i+1)]);
0215      cr1=ps1*cr1;
0216      cr2=reshape(cr2,[r(i+1)*n(i+1),r(i+2)]);
0217      cr2=cr2*ps2;
0218      cr1=reshape(cr1,[ry(i)*n(i),r(i+1)]);
0219      cr2=reshape(cr2,[r(i+1),n(i+1)*ry(i+2)]);
0220      cr=cr1*cr2;
0221      cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0222      cr=fun(cr); %Elements are evaluated here!
0223      cr=reshape(cr,[ry(i)*n(i)*n(i+1),ry(i+2)]);
0224      cr = cr/(px2.');
0225      cr=reshape(cr,[ry(i),n(i)*n(i+1)*ry(i+2)]);
0226      cr=px1 \cr;
0227      cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0228      %Check for local approximation of cr for the error
0229      %cry1=cry(pos1-ry(i)*n(i)*ry(i+1):pos1-1);
0230      cry1=cry_old(psy(i):psy(i+1)-1);
0231      %cry2=cry(ry(:ry(i+1)*n(i+1)*ry(i+2));
0232      %cry1=cry(1:ry(i)*n(i)*ry(i+1));
0233      %cry2=cry(ry(i)*n(i)*ry(i+1)+1:ry(i)*n(i)*ry(i+1)+ry(i+1)*n(i+1)*ry(i+2));
0234      cry2=cry(1:ry(i+1)*n(i+1)*ry(i+2));
0235      cry(1:ry(i+1)*n(i+1)*ry(i+2))=[];
0236      %cry2=cry_old(psy(i+1):psy(i+2)-1);
0237      %cry(1:(ry(i+1)*n(i+1)*ry(i+2)))=[]; %Delete both of first cores
0238      %cry(1:ry(i)*n(i)*ry(i+1)+ry(i+1)*n(i+1)*ry(i+2))=[];
0239      cry1=reshape(cry1,[ry(i)*n(i),ry(i+1)]);
0240      cry2=reshape(cry2,[ry(i+1),n(i+1)*ry(i+2)]);
0241      appr=cry1*cry2;
0242      er=norm(appr-cr,'fro')/norm(cr,'fro');
0243      %er
0244           max_er=max(er,max_er);
0245 
0246      %Compute SVD of cr
0247      [u,s,v]=svd(cr,'econ');
0248      s=diag(s);
0249      r2=my_chop2(s,eps*norm(s)/sqrt(d-1));
0250      s=s(1:r2); u=u(:,1:r2); v=v(:,1:r2);
0251      %Make it standard
0252      u=u*diag(s);
0253 
0254 
0255      %Kick rank
0256 
0257       vr=randn(size(v,1),kick_rank);
0258       v=reort(v,vr);
0259       radd=size(v,2)-r2;
0260       if ( radd > 0 )
0261          ur=zeros(size(u,1),radd);
0262          u=[u,ur];
0263       end
0264       r2=size(v,2);
0265 
0266 
0267 
0268      v=v.';v0=v;
0269      %Compute new phi;
0270      ry(i+1)=r2;
0271      u=u(:); u=u.'; v=v(:); v=v.';
0272      cry=[u,v,cry];
0273      %keyboard;
0274      %We need new memory for
0275      %cry(pos1:pos1+ry(i+1)*n(i+1)*ry(i+2)-1)=v(:); %Here memory has to be (?) enlarged
0276      %if ( pos1 <= ry(i)*n(i)*ry(i+1) ) %Have to enlarge memory
0277      %  cry=cry(pos1:numel(cry));
0278      %  cry=[u(:)',cry];
0279      %  pos1=ry(i)*n(i)*ry(i+1)+1;
0280      %else
0281      %   pos1=pos1-ry(i)*n(i)*ry(i+1);
0282       %  cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1)=u(:);
0283      %end
0284      %Compute new maxvol and (new) submatrices
0285      v0=reshape(v0,[ry(i+1)*n(i+1),ry(i+2)]);
0286      v0=v0*px2.';
0287      v0=reshape(v0,[ry(i+1),n(i+1)*ry(i+2)]);
0288      v0=v0.';
0289      ind=maxvol2(v0);
0290      phx{i+1}=v0(ind,:);
0291      %Now we have to: cr1 with phi from the left
0292      phi{i+1}=cr2(:,ind);
0293 
0294  end
0295 
0296   psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0297 
0298 y.core=cry;
0299 y.r=ry;
0300 y.ps=psy;
0301 if ( isempty(yold) )
0302  yold=y;
0303  er_nrm=1;
0304 else
0305 
0306    er_nrm=norm(yold-y)/norm(y);
0307    yold=y;
0308 end
0309  fprintf('sweep=%d, er=%3.2e er_nrm=%3.2e \n',swp,max_er,er_nrm);
0310 
0311 swp=swp+1;
0312 end
0313   psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0314 
0315 y.core=cry;
0316 y.r=ry;
0317 y.ps=psy;
0318 
0319 end

Generated on Wed 08-Feb-2012 18:20:24 by m2html © 2005