Home > tt2 > core > tt_compr2.m

tt_compr2

PURPOSE ^

Tensor rounding in TT1.0 format

SYNOPSIS ^

function [tt] = tt_compr2(tt,eps, max_r)

DESCRIPTION ^

Tensor rounding in TT1.0 format
   [TT]=TT_COMPR2(TT,EPS) Reapproximates the given TT-tensor with 
   prescribed accuracy EPS. Please avoid its usage: it will be removed in
   future releases. Use round() from the object-oriented version


 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 [tt] = tt_compr2(tt,eps, max_r)
0002 %Tensor rounding in TT1.0 format
0003 %   [TT]=TT_COMPR2(TT,EPS) Reapproximates the given TT-tensor with
0004 %   prescribed accuracy EPS. Please avoid its usage: it will be removed in
0005 %   future releases. Use round() from the object-oriented version
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 d = size(tt,1);
0019 %First, estimate the logarithm of the squared norm, and then --- the norm
0020 %of each core :-)
0021 nrm_full=tt_dot2(tt,tt);
0022 nrm1=nrm_full/(2*d); nrm1=exp(nrm1);
0023 
0024 exists_max_r=1;
0025 if ((nargin<3)||(isempty(max_r)))
0026     exists_max_r=0;
0027 end;
0028 
0029 if ( nrm_full < log(1e-200) ) %Something really small
0030   n=size(tt{1},1);
0031   tt{1}=zeros(n,1);
0032   n=size(tt{d},1);
0033   tt{d}=ones(n,1);
0034   for i=2:d-1
0035   n=size(tt{i},1);
0036   tt{i}=ones(n,1,1);
0037   end
0038   return
0039 end
0040 %nrmf=zeros(d,1); %Place to store the norms of QR-factors
0041 %first, we orthogonalize the tensor from right to left until the first mode
0042 mat=tt{d};
0043 [q,rv]=qr(mat,0); rv=rv./nrm1; q=q.*nrm1;
0044 tt{d}=q;
0045 for i=(d-1):-1:2
0046     tt{i} = ten_conv(tt{i},3,conj(rv'));
0047     ncur=size(tt{i},1);
0048     r2=size(tt{i},2);
0049     r3=size(tt{i},3);
0050     core=permute(tt{i},[1,3,2]);
0051     core=reshape(core,[ncur*r3,r2]);
0052     [tt{i},rv]=qr(core,0); rv=rv./nrm1;
0053     rnew=min(r2,ncur*r3);
0054     tt{i}=reshape(tt{i}.*nrm1,[ncur,r3,rnew]);
0055     tt{i}=permute(tt{i},[1,3,2]);
0056 end
0057 tt{1}=tt{1}*conj(rv');
0058 %nrmf(1)=norm(tt{1},'fro');
0059 %nrm_full=sum(log(nrmf(1:d))); nrm1=nrm_full/d; nrm1=exp(nrm1); %This would
0060 %be the norm of each core
0061 %Now gradually start compression from the left, using the knowledge
0062 %of norms
0063 mat=tt{1};
0064 %return;
0065 mat(abs(mat)<1e-300)=0;
0066 [u0,s0,ru]=svd(mat,0); 
0067 %If no scaling factors were taken out,
0068 %then everything would be simple --- nrm=norm(diag(s0)) is the norm,
0069 %singular values are filtered at absolute accuracy eps*nrm/sqrt(d-1)
0070 %Here the "True" s0 matrix is up to factor of product of nrm(2:d)
0071 %so for it we can filter the singular values just at
0072 %eps*nrmf(1)/sqrt{d-1}
0073 %nrmf(1)=norm(diag(s0));
0074 %nrm=norm(diag(s0));
0075 eps1=eps*norm(diag(s0))/sqrt(d-1); %This is the absolute accuracy to filter with
0076 %r0=my_chop2(diag(s0),eps1);
0077 r0=numel(find(s0>eps1));
0078 if (exists_max_r) r0 = min(r0, max_r); end;
0079 %keyboard;
0080 %r0=rank(mat,eps1);
0081 u0=u0(:,1:r0);
0082 s0=diag(s0);
0083 s0=s0(1:r0); % -eps1*sign(s0);
0084 ru=ru(:,1:r0)*diag(s0)./nrm1; %This should be scaled properly
0085 %ru=ru;
0086 tt{1}=u0.*nrm1; %Now it is properly scaled
0087 for i=2:d-1
0088     %Convolve tt{i} over the second index
0089 %     fprintf('norm_tt{%d}=%g, norm_ru = %g\n', i, norm(reshape(tt{i}, size(tt{i},1)*size(tt{i},2), size(tt{i},3)), 'fro'), norm(ru,'fro'));
0090     tt{i}=ten_conv(tt{i},2,conj(ru));
0091     ncur=size(tt{i},1);
0092     r2=size(tt{i},2);
0093     r3=size(tt{i},3);
0094     core=reshape(tt{i},[ncur*r2,r3]);
0095     %r=rank(core,eps1);
0096     %keyboard;
0097     core(abs(core)<1e-300)=0;
0098     [u0,s0,ru]=svd(core,0);
0099     
0100     nrm=norm(diag(s0));
0101     eps1=eps*nrm/sqrt(d-1); %Nothing more
0102     %keyboard;
0103     %r=my_chop2(diag(s0),eps1);
0104     r=numel(find(s0>eps1));
0105     if (exists_max_r) r = min(r, max_r); end;
0106     u0=u0(:,1:r);
0107     s0=(s0(1:r,1:r))./nrm1;
0108     ru=ru(:,1:r)*s0;
0109     core=u0.*nrm1;
0110     tt{i}=reshape(core,[ncur,r2,r]);
0111 end
0112 tt{d}=tt{d}*conj(ru);
0113 return
0114 end

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