0001 function [y]=funcrs2(tt,fun,eps,y,nswp)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 rmin=1;
0023 verb=true;
0024 kick_rank=5;
0025 if (~isempty(y))
0026 yold=y;
0027 end
0028 y1=y;
0029
0030
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;
0045 phx{1}=1;
0046
0047 cry_old=cry;
0048 psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0049 pos1=psy(d+1);
0050
0051 for i=d-1:-1:1
0052
0053
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
0059
0060
0061
0062 [u,s,v]=svd(cr,'econ'); s=diag(s);
0063 ry(i+1) = my_chop2(s,norm(s)*eps/sqrt(d-1));
0064
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);
0068 rm=u.';
0069 ry(i+1)=size(cr,2);
0070
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
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};
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;
0107 psy=cumsum([1;n.*ry(1:d).*ry(2:d+1)]);
0108 pos1=1;
0109 for i=1:d-1
0110
0111
0112
0113
0114 ps1=phi{i}; ps2=phi{i+2}; px1=phx{i}; px2=phx{i+2};
0115
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
0126 cr=fun(cr);
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
0133 cry1=cry(pos1:pos1+ry(i)*n(i)*ry(i+1)-1);
0134
0135
0136
0137
0138
0139
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
0147 max_er=max(er,max_er);
0148
0149
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
0158 ur=randn(size(u,1),kick_rank);
0159
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
0170
0171
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
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
0187 phi{i+1}=cr1(ind,:);
0188
0189
0190 end
0191
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
0199
0200
0201
0202 cry=cry(psy(d):psy(d+1)-1);
0203 for i=d-1:-1:1
0204
0205
0206
0207
0208 ps1=phi{i}; ps2=phi{i+2}; px1=phx{i}; px2=phx{i+2};
0209
0210
0211
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);
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
0229
0230 cry1=cry_old(psy(i):psy(i+1)-1);
0231
0232
0233
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
0237
0238
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
0244 max_er=max(er,max_er);
0245
0246
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
0252 u=u*diag(s);
0253
0254
0255
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
0270 ry(i+1)=r2;
0271 u=u(:); u=u.'; v=v(:); v=v.';
0272 cry=[u,v,cry];
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
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
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