0001 function t = qtt_tucker(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 if (nargin == 0)
0033 t.core=tt_tensor;
0034 t.tuck=cell(0);
0035 t.dphys=0;
0036 t.sz=0;
0037 t = class(t, 'qtt_tucker');
0038 return;
0039 end
0040
0041
0042 if (nargin == 1) && isa(varargin{1}, 'qtt_tucker')
0043 t=qtt_tucker;
0044 t.core = varargin{1}.core;
0045 t.tuck = varargin{1}.tuck;
0046 t.sz = varargin{1}.sz;
0047 t.dphys=varargin{1}.dphys;
0048 return;
0049 end
0050
0051
0052 if ( isa(varargin{1},'tt_tensor') )
0053 if ( nargin == 3 )
0054 if (isa(varargin{2}, 'cell'))&&(isa(varargin{3}, 'double'))
0055
0056 tt=varargin{1};
0057 sz=varargin{2};
0058 eps=varargin{3};
0059 [fc,cr]=qtt_tucker_m(tt,sz,eps);
0060 t=qtt_tucker;
0061 t.core=cr;
0062 t.tuck=fc;
0063 t.sz=sz;
0064 t.dphys=numel(sz);
0065 else
0066
0067 t = linqtt_to_qtttucker(varargin{1}, varargin{2}, varargin{3});
0068 end;
0069 else
0070 tt=varargin{1};
0071 eps=varargin{2};
0072 n=tt.n;
0073 d=tt.d;
0074 sz=cell(d,1);
0075 for i=1:d
0076 sz{i}=2*ones(1,log2(n(i)));
0077 end
0078 [fc,cr]=qtt_tucker_m(tt,sz,eps);
0079 t=qtt_tucker;
0080 t.core=cr;
0081 t.tuck=fc;
0082 t.sz=sz;
0083 t.dphys=numel(sz);
0084 end;
0085 end
0086
0087
0088 if (nargin==2) && isa(varargin{1}, 'cell') && isa(varargin{2}, 'tt_tensor')
0089 t = qtt_tucker;
0090 t.core = varargin{2};
0091 t.dphys = numel(varargin{1});
0092 t.tuck = cell(t.dphys, 1);
0093 t.sz = cell(t.dphys, 1);
0094 for i=1:t.dphys
0095 t.tuck{i} = varargin{1}{i};
0096 if (isa(t.tuck{i}, 'double'))
0097 t.tuck{i} = tt_tensor(t.tuck{i});
0098 end;
0099 t.sz{i} = t.tuck{i}.n;
0100 end;
0101
0102 end;
0103
0104
0105 if ( nargin ==3 && isa(varargin{1},'double') && isa(varargin{2},'cell') && isa(varargin{3},'double'))
0106
0107 t=qtt_tucker;
0108 a=varargin{1};
0109 sz1=numel(a);
0110 sz=varargin{2};
0111 eps=varargin{3};
0112 eps0=eps;
0113
0114
0115 d=numel(sz);
0116 n=zeros(d,1);
0117 for i=1:d
0118 n(i)=prod(sz{i});
0119 end
0120 if ( sz1 ~= prod(n) )
0121 error('qtt_tucker: check_sizes');
0122 end
0123 rtt=zeros(d+1,1);
0124 rtuck=zeros(d,1);
0125 tuck=cell(d,1);
0126 rtt(1)=1; rtt(d+1)=1;
0127 tt_core=[];
0128 for k=1:d-1
0129 a=reshape(a,[rtt(k),n(k),numel(a)/(n(k)*rtt(k))]);
0130
0131 a=permute(a,[2,1,3]);
0132 a=reshape(a,[n(k),numel(a)/n(k)]);
0133 [u,s,v]=svd(a,'econ');
0134 s=diag(s);
0135 r=my_chop2(s,norm(s)*eps0);
0136 rtuck(k)=r;
0137 u=u(:,1:r); s=s(1:r);
0138 v=v(:,1:r);
0139 u=u*diag(s);
0140 tuck{k}=tt_tensor(u,sz{k},1,r,eps0);
0141 [tuck{k},rm]=qr(tuck{k},'lr');
0142
0143
0144 v=rm*v';
0145
0146 v=reshape(v,[r,rtt(k),numel(v)/(r*rtt(k))]);
0147 v=permute(v,[2,1,3]);
0148 v=reshape(v,[rtt(k)*r,numel(v)/(r*rtt(k))]);
0149 [u1,s1,v1]=svd(v,'econ');
0150 s1=diag(s1);
0151 r1=my_chop2(s1,norm(s1)*eps);
0152 rtt(k+1)=r1;
0153 u1=u1(:,1:r1);s1=s1(1:r1); v1=v1(:,1:r1);
0154 a=diag(s1)*v1';
0155 tt_core=[tt_core;u1(:)];
0156 end
0157
0158 a=reshape(a,[rtt(d),n(d),numel(a)/(n(d)*rtt(d))]);
0159 a=permute(a,[2,1,3]);
0160 a=reshape(a,[sz{d},numel(a)/n(d)]);
0161 tuck{d}=tt_tensor(a,sz{d},1,r,eps0);
0162 [tuck{d},rm]=qr(tuck{d},'lr');
0163 a=rm; a=reshape(a,[r,rtt(d),numel(a)/(r*rtt(d))]);
0164 a=permute(a,[1,2,3]);
0165 rtuck(d)=r;
0166 tt_core=[tt_core;a(:)];
0167 rtt(d+1)=size(a,3);
0168 cr=tt_tensor;
0169 cr.d=d;
0170 cr.n=rtuck;
0171 cr.r=rtt;
0172 cr.core=tt_core;
0173 cr.ps=cumsum([1;cr.n.*cr.r(1:cr.d).*cr.r(2:cr.d+1)]);
0174 t.core=cr;
0175 t.tuck=tuck;
0176 t.dphys=d;
0177 t.sz=sz;
0178
0179 end
0180
0181
0182 return