Home > tt2 > @tt_tensor > funcrs.m

funcrs

PURPOSE ^

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

SYNOPSIS ^

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

DESCRIPTION ^

Cross approximation of a function of a TT-tensor, Method 1
   [Y]=FUNCRS(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]=funcrs(tt,fun,eps,y,nswp,varargin)
0002 %Cross approximation of a function of a TT-tensor, Method 1
0003 %   [Y]=FUNCRS(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 dropsweeps = 4;
0024 kick_rank=10;
0025 verb=true;
0026 if (~isempty(y))
0027    yold=y;
0028 end
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 core=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 %Warmup procedure: orthogonalize from right-to-left & maxvol
0044 pos1=psy(d);
0045 %Cores i
0046 for i=d-1:-1:1
0047    cr=cry(pos1:pos1+ry(i+1)*n(i+1)*ry(i+2)-1);
0048    cr2=cry(pos1-ry(i)*n(i)*ry(i+1):pos1-1);
0049    cr2=reshape(cr2,[ry(i)*n(i),ry(i+1)]);
0050    cr=reshape(cr,[ry(i+1),n(i+1)*ry(i+2)]);
0051    cr=cr.';
0052    [cr,rm]=qr(cr,0); 
0053    ry(i+1)=size(cr,2);
0054    ind=maxvol2(cr); 
0055    r1=cr(ind,:);
0056    cr=cr/r1;
0057    cr=cr.';
0058    cry(pos1:pos1+ry(i+1)*n(i+1)*ry(i+2)-1)=cr(:);
0059    pos1=pos1-ry(i)*n(i)*ry(i+1);
0060    cr2=cr2*(r1*rm).'; 
0061    cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1)=cr2(:);
0062    %Take phi matrix; convolve from right with current cors of V
0063    cr0=core(ps(i+1):ps(i+2)-1);
0064    cr0=reshape(cr0,[r(i+1)*n(i+1),r(i+2)]); 
0065    cr0=cr0*phi{i+2}; %cr0 is now r(i)*n(i)*ry(i+1);
0066    cr0=reshape(cr0,[r(i+1),n(i+1)*ry(i+2)]);
0067    phi{i+1}=cr0(:,ind); 
0068  %  psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0069 %y.core=cry;
0070 %y.r=ry;
0071 %y.ps=psy;
0072 %keyboard
0073 
0074    %Orthogonalization & maxvol is "local operation" (touches two
0075    %cores)
0076    %Computation of elements requries storage of phi matrices
0077 end
0078 %Truncate cry
0079 %pos1=pos1-n(1)*r(2);
0080 cry=cry(pos1:numel(cry));
0081 y.core=cry;
0082 y.r=ry;
0083 y.ps=psy;
0084 %keyboard
0085 swp=1;
0086 
0087 yold=[];
0088 not_converged = true;
0089 pos1=1;
0090 last_sweep = false;
0091 while ( swp < nswp && not_converged )
0092     max_er=0;
0093 cry_old=cry;
0094 psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0095 pos1=1;
0096  for i=1:d-1
0097      %fprintf('i=%d \n',i);
0098      %We care for two cores, with number i & number i+1, and use
0099      %psi(i) and psi(i+2) as a basis; also we will need to recompute
0100      %psi(i+1)
0101      ps1=phi{i}; ps2=phi{i+2};
0102      %Take current core; convolve it with
0103      %core=core(ps
0104      %Compute (!) superblock and function (!) of it
0105      cr1=core(ps(i):ps(i+1)-1);
0106      cr2=core(ps(i+1):ps(i+2)-1);
0107      cr1=reshape(cr1,[r(i),n(i)*r(i+1)]);
0108      cr1=ps1*cr1;
0109      cr2=reshape(cr2,[r(i+1)*n(i+1),r(i+2)]);
0110      cr2=cr2*ps2;
0111      cr1=reshape(cr1,[ry(i)*n(i),r(i+1)]);
0112      cr2=reshape(cr2,[r(i+1),n(i+1)*ry(i+2)]);
0113      cr=cr1*cr2;
0114      cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0115      cr=fun(cr); %Elements are evaluated here!
0116      cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0117      %Check for local approximation of cr for the error
0118      cry1=cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1);
0119 
0120      cry2=cry_old(psy(i+1):psy(i+2)-1);
0121      
0122      cry1=reshape(cry1,[ry(i)*n(i),ry(i+1)]);
0123      cry2=reshape(cry2,[ry(i+1),n(i+1)*ry(i+2)]);
0124      appr=cry1*cry2;
0125      er=norm(appr-cr,'fro')/norm(cr,'fro');
0126      max_er=max(er,max_er);
0127      %Compute SVD of cr
0128 
0129      if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0130          [u,s,v]=svd(cr-appr,'econ');
0131      else
0132          [u,s,v]=svd(cr,'econ');
0133      end;
0134      s=diag(s);
0135      r2=my_chop2(s,eps*norm(cr,'fro')/sqrt(d-1));
0136      s=s(1:r2); u=u(:,1:r2); v=v(:,1:r2);
0137      
0138      v=conj(v)*diag(s);
0139 
0140      if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0141          u = [cry1, u];
0142          v = [cry2.', v];
0143          [u,rv]=qr(u,0);
0144          v = v*(rv.');         
0145      else
0146          if (~last_sweep)
0147              %Kick rank of u
0148              ur=randn(size(u,1),kick_rank);
0149              %Orthogonalize ur to u by Golub-Kahan reorth
0150              u=reort(u,ur);
0151              radd=size(u,2)-r2;
0152              if ( radd > 0 )
0153                  vr=zeros(size(v,1),radd);
0154                  v=[v,vr];
0155              end
0156          end;
0157      end;
0158      
0159      %vr=randn(size(v,1),kick_rank);
0160      %v=reort(v,vr);
0161      %radd=size(v,2)-rnew;
0162      %if ( radd > 0 )
0163      %    ur=zeros(size(u,1),radd);
0164      %    u=[u,ur];
0165      %end
0166      %rnew=rnew+radd;
0167 
0168      
0169      
0170      
0171      %u=[u,uadd]; v=[v,vadd];
0172      %[u,ru]=qr(u,0);
0173      %v=v*(ru.');
0174      r2=size(u,2);
0175      
0176      ind=maxvol2(u);
0177      r1=u(ind,:); 
0178      u=u/r1; v=v*r1'; v=v.';
0179      %Compute new phi
0180      ry(i+1)=r2;
0181      cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1)=u(:);
0182      pos1=pos1+ry(i)*n(i)*ry(i+1);
0183      cry(pos1:pos1+ry(i+1)*n(i+1)*ry(i+2)-1)=v(:);
0184      
0185      %Now we have to: cr1 with phi from the left
0186      phi{i+1}=cr1(ind,:); %phi{i+1}=phi{i+1};
0187      
0188      
0189  end
0190   %Truncate local memory
0191   cry=cry(1:pos1+ry(d)*n(d)*ry(d+1)-1);
0192   psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0193 y.core=cry;
0194 y.r=ry;
0195 y.ps=psy;
0196 %keyboard;
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};
0209      %Take current core; convolve it with
0210      %core=core(ps
0211      %Compute (!) superblock and function (!) of it
0212      cr1=core(ps(i):ps(i+1)-1);
0213      cr2=core(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      %Check for local approximation of cr for the error
0225      %cry1=cry(pos1-ry(i)*n(i)*ry(i+1):pos1-1);
0226      cry1=cry_old(psy(i):psy(i+1)-1);
0227      %cry2=cry(ry(:ry(i+1)*n(i+1)*ry(i+2));
0228      %cry1=cry(1:ry(i)*n(i)*ry(i+1));
0229      %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));
0230      cry2=cry(1:ry(i+1)*n(i+1)*ry(i+2));
0231      cry(1:ry(i+1)*n(i+1)*ry(i+2))=[];
0232      %cry2=cry_old(psy(i+1):psy(i+2)-1);
0233      %cry(1:(ry(i+1)*n(i+1)*ry(i+2)))=[]; %Delete both of first cores
0234      %cry(1:ry(i)*n(i)*ry(i+1)+ry(i+1)*n(i+1)*ry(i+2))=[];
0235      cry1=reshape(cry1,[ry(i)*n(i),ry(i+1)]);
0236      cry2=reshape(cry2,[ry(i+1),n(i+1)*ry(i+2)]);
0237      appr=cry1*cry2;
0238      er=norm(appr-cr,'fro')/norm(cr,'fro');
0239      %er
0240      max_er=max(er,max_er);
0241           
0242      if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0243          [u,s,v]=svd(cr-appr,'econ');
0244      else
0245          %Compute SVD of cr
0246          [u,s,v]=svd(cr,'econ');
0247      end;
0248      s=diag(s);
0249      r2=my_chop2(s,eps*norm(cr,'fro')/sqrt(d-1));
0250      s=s(1:r2); u=u(:,1:r2); v=conj(v(:,1:r2));
0251      %Make it standard
0252      u=u*diag(s);
0253      
0254      
0255      if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0256          u = [cry1, u];
0257          v = [cry2.', v];
0258          [v,rv]=qr(v,0);
0259          u = u*(rv.');
0260      else
0261          if (~last_sweep)
0262              %Kick rank
0263              vr=randn(size(v,1),kick_rank);
0264              v=reort(v,vr);
0265              radd=size(v,2)-r2;
0266              if ( radd > 0 )
0267                  ur=zeros(size(u,1),radd);
0268                  u=[u,ur];
0269              end
0270          end;
0271      end;
0272 
0273      
0274      
0275      r2=size(v,2);
0276      ind=maxvol2(v);
0277      r1=v(ind,:); 
0278      v=v/r1; v=v.';
0279      u=u*r1';
0280      %Compute new phi;
0281      ry(i+1)=r2;
0282      u=u(:); u=u'; v=v(:); v=v';
0283      cry=[u,v,cry];
0284      %keyboard;
0285      %We need new memory for
0286      %cry(pos1:pos1+ry(i+1)*n(i+1)*ry(i+2)-1)=v(:); %Here memory has to be (?) enlarged
0287      %if ( pos1 <= ry(i)*n(i)*ry(i+1) ) %Have to enlarge memory
0288      %  cry=cry(pos1:numel(cry));
0289      %  cry=[u(:)',cry];
0290      %  pos1=ry(i)*n(i)*ry(i+1)+1;
0291      %else
0292      %   pos1=pos1-ry(i)*n(i)*ry(i+1);
0293       %  cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1)=u(:);
0294      %end
0295      %Now we have to: cr1 with phi from the left
0296      phi{i+1}=cr2(:,ind); phi{i+1}=phi{i+1};
0297  
0298  end
0299  %Truncate local memory
0300  %cry=cry(pos1:numel(cry));
0301 
0302 % keyboard;
0303   psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0304 
0305 y.core=cry;
0306 y.r=ry;
0307 y.ps=psy;
0308 %keyboard;
0309 if ( isempty(yold) )
0310  yold=y;
0311  er_nrm=1;
0312 else
0313    
0314    er_nrm=norm(yold-y)/norm(y);
0315    yold=y;
0316 end
0317 if ( verb )
0318  fprintf('sweep=%d, er=%3.2e er_nrm=%3.2e \n',swp,max_er,er_nrm);
0319 end
0320 if (last_sweep)
0321     break;
0322 end;
0323 if (er_nrm<eps)
0324     last_sweep=true;
0325 end;
0326 swp=swp+1;
0327 end     
0328   psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0329 
0330 y.core=cry;
0331 y.r=ry;
0332 y.ps=psy;
0333 
0334 end

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