0001 function [y]=funcrs(tt,fun,eps,y,nswp,varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 rmin=1;
0023 dropsweeps = 4;
0024 kick_rank=10;
0025 verb=true;
0026 if (~isempty(y))
0027 yold=y;
0028 end
0029
0030
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
0044 pos1=psy(d);
0045
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
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};
0066 cr0=reshape(cr0,[r(i+1),n(i+1)*ry(i+2)]);
0067 phi{i+1}=cr0(:,ind);
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 end
0078
0079
0080 cry=cry(pos1:numel(cry));
0081 y.core=cry;
0082 y.r=ry;
0083 y.ps=psy;
0084
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
0098
0099
0100
0101 ps1=phi{i}; ps2=phi{i+2};
0102
0103
0104
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);
0116 cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0117
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
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
0148 ur=randn(size(u,1),kick_rank);
0149
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
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174 r2=size(u,2);
0175
0176 ind=maxvol2(u);
0177 r1=u(ind,:);
0178 u=u/r1; v=v*r1'; v=v.';
0179
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
0186 phi{i+1}=cr1(ind,:);
0187
0188
0189 end
0190
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
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};
0209
0210
0211
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);
0223 cr=reshape(cr,[ry(i)*n(i),n(i+1)*ry(i+2)]);
0224
0225
0226 cry1=cry_old(psy(i):psy(i+1)-1);
0227
0228
0229
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
0233
0234
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
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
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
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
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
0281 ry(i+1)=r2;
0282 u=u(:); u=u'; v=v(:); v=v';
0283 cry=[u,v,cry];
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296 phi{i+1}=cr2(:,ind); phi{i+1}=phi{i+1};
0297
0298 end
0299
0300
0301
0302
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
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