0001 function [x, sweeps]=dmrg_solve2(A, y, eps,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
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 max_full_size=2500;
0045 prec_compr=1e-3;
0046 prec_tol=1e-1;
0047 prec_iters=10;
0048
0049 dropsweeps=1;
0050 ddpow = 0.1;
0051 min_dpow = 1;
0052 ddrank = 1;
0053 min_drank = 1;
0054 d_pow_check = 0;
0055 bot_conv = 0.1;
0056 top_conv = 0.99;
0057
0058 bs_treshold = 0.0001*0;
0059 trunc_to_true = 1.5;
0060
0061 use_self_prec=false;
0062 nswp=10;
0063 nrestart=40;
0064 gmres_iters=2;
0065
0066 local_prec = 'selfprec';
0067 local_format = 'full';
0068
0069 rmax=1000;
0070 tol=eps;
0071 verb=1;
0072 kickrank = 2;
0073 x0=[];
0074 P=[];
0075 for i=1:2:length(varargin)-1
0076 switch lower(varargin{i})
0077 case 'nswp'
0078 nswp=varargin{i+1};
0079 case 'rmax'
0080 rmax=lower(varargin{i+1});
0081 case 'x0'
0082 x0=varargin{i+1};
0083 case 'verb'
0084 verb=varargin{i+1};
0085 case 'p'
0086 P=varargin{i+1};
0087 case 'tol'
0088 tol=varargin{i+1};
0089 case 'local_prec'
0090 local_prec=varargin{i+1};
0091 case 'nrestart'
0092 nrestart=varargin{i+1};
0093 case 'gmres_iters'
0094 gmres_iters=varargin{i+1};
0095 case 'kickrank'
0096 kickrank=varargin{i+1};
0097 case 'max_full_size'
0098 max_full_size=varargin{i+1};
0099 case 'prec_compr'
0100 prec_compr=varargin{i+1};
0101 case 'prec_tol'
0102 prec_tol=varargin{i+1};
0103 case 'prec_iters'
0104 prec_iters=varargin{i+1};
0105 case 'use_self_prec'
0106 use_self_prec=varargin{i+1};
0107 case 'ddpow'
0108 ddpow=varargin{i+1};
0109 case 'ddrank'
0110 ddrank=varargin{i+1};
0111 case 'd_pow_check'
0112 d_pow_check=varargin{i+1};
0113 case 'bot_conv'
0114 bot_conv=varargin{i+1};
0115 case 'top_conv'
0116 top_conv=varargin{i+1};
0117 case 'min_dpow'
0118 min_dpow=varargin{i+1};
0119 case 'min_drank'
0120 min_drank=varargin{i+1};
0121 otherwise
0122 error('Unrecognized option: %s\n',varargin{i});
0123 end
0124 end
0125
0126 input_is_tt_tensor = 0;
0127
0128 if ( isa(y,'tt_tensor') )
0129 y=core(y);
0130 input_is_tt_tensor = 1;
0131 end
0132
0133 if (isa(y, 'tt_tensor'))
0134 y=core(y);
0135 input_is_tt_tensor = 1;
0136 end;
0137 if ( isa(A,'tt_matrix') )
0138
0139
0140 A=core(A);
0141 input_is_tt_tensor = 1;
0142
0143
0144
0145
0146
0147
0148
0149
0150 end
0151
0152 if (isempty(x0))
0153 x0=tt_random(tt_size(y), max(size(y)), 2);
0154 end;
0155 if ( isa(P,'tt_matrix') )
0156 P=core(P);
0157 input_is_tt_tensor = 1;
0158 end;
0159 if ( isa(x0,'tt_tensor') )
0160 x0=core(x0);
0161 input_is_tt_tensor = 1;
0162 end
0163
0164
0165
0166 d=size(A,1);
0167
0168 if ( isempty(P) )
0169 P = core(tt_eye(tt_size(y), d));
0170 end
0171 x=x0;
0172
0173 x{1}=reshape(x{1}, size(x{1},1), 1, size(x{1},2));
0174 y{1}=reshape(y{1}, size(y{1},1), 1, size(y{1},2));
0175 A{1}=reshape(A{1}, size(A{1},1),size(A{1},2), 1, size(A{1},3));
0176 P{1}=reshape(P{1}, size(P{1},1),size(P{1},2), 1, size(P{1},3));
0177
0178 phA = cell(d,1);
0179 phy = cell(d,1);
0180 dx_old = ones(d,1);
0181 dx = zeros(d,1);
0182
0183 drank = ones(d,1)*min_drank;
0184
0185 dpows = ones(d,1)*min_dpow;
0186
0187
0188
0189
0190
0191
0192 sol_hist = cell(3,1);
0193 sol_hist{1}=x;
0194 max_res_old = 0;
0195 last_sweep = false;
0196 for swp=1:nswp
0197
0198
0199 rvx = 1; rnewx=1; phAold=1; phyold=1;
0200
0201 for i=1:d-1
0202 cre = x{i};
0203 n1 = size(cre,1); rx1 = size(cre,2); rx2 = size(cre,3);
0204 cre = reshape(permute(cre, [2 1 3]), rx1, n1*rx2);
0205 cre = rvx*cre;
0206 rx1=rnewx;
0207 cre = reshape(cre, rx1*n1, rx2);
0208 [q,rvx]=qr(cre,0);
0209 rnewx = min(rx1*n1, rx2);
0210 x{i}=permute(reshape(q, rx1, n1, rnewx), [2 1 3]);
0211
0212
0213 a1 = A{i};
0214 n1=size(a1,1); m1=size(a1,2); ra1=size(a1,3); ra2=size(a1,4);
0215 p1 = P{i};
0216 k1=size(p1,1); rp1=size(p1,3); rp2=size(p1,4);
0217 y1 = y{i};
0218 ry1=size(y1,2); ry2=size(y1,3);
0219 x1 = x{i};
0220
0221 rxm1=size(x1,2); rxm2=size(x1,3); rxn1=rxm1; rxn2=rxm2;
0222 phAold = reshape(phAold, rxn1*rp1*ra1, rxm1);
0223 x1 = reshape(permute(x1, [2 1 3]), rxm1, m1*rxm2);
0224 phAold=phAold*x1;
0225 phAold=reshape(phAold, rxn1, rp1, ra1, m1, rxm2);
0226 phAold=reshape(permute(phAold, [1 2 5 4 3]), rxn1*rp1*rxm2, m1*ra1);
0227 a1 = reshape(permute(a1, [2 3 1 4]), m1*ra1, n1*ra2);
0228 phAold=phAold*a1;
0229 phAold=reshape(phAold, rxn1, rp1, rxm2, n1, ra2);
0230 phAold=reshape(permute(phAold, [1 3 5 4 2]), rxn1*rxm2*ra2, n1*rp1);
0231 p1 = reshape(permute(p1, [2 3 1 4]), n1*rp1, k1*rp2);
0232 phAold=phAold*p1;
0233 phAold=reshape(phAold, rxn1, rxm2, ra2, k1, rp2);
0234 phAold=reshape(permute(phAold, [2 5 3 4 1]), rxm2*rp2*ra2, k1*rxn1);
0235 x1 = reshape(x{i}, k1*rxn1, rxn2);
0236 phAold=phAold*conj(x1);
0237 phAold = reshape(phAold, rxm2, rp2, ra2, rxn2);
0238 phAold = permute(phAold, [4 2 3 1]);
0239 phA{i}=phAold;
0240
0241 phyold = reshape(phyold, rxn1*rp1, ry1);
0242 y1 = reshape(permute(y1, [2 1 3]), ry1, n1*ry2);
0243 phyold=phyold*y1;
0244 phyold = reshape(phyold, rxn1, rp1, n1, ry2);
0245 phyold=reshape(permute(phyold, [1 4 3 2]), rxn1*ry2, n1*rp1);
0246 p1=reshape(permute(P{i}, [2 3 1 4]), n1*rp1, k1*rp2);
0247 phyold=phyold*p1;
0248 phyold=reshape(phyold, rxn1, ry2, k1, rp2);
0249 phyold=reshape(permute(phyold, [4 2 3 1]), rp2*ry2, k1*rxn1);
0250 x1=reshape(x{i}, k1*rxn1, rxn2);
0251 phyold=phyold*conj(x1);
0252 phyold=permute(reshape(phyold, rp2, ry2, rxn2), [3 1 2]);
0253 phy{i}=phyold;
0254 end;
0255
0256 cre = x{d};
0257 n1 = size(cre,1); rx1 = size(cre,2); rx2 = size(cre,3);
0258 cre = reshape(permute(cre, [2 1 3]), rx1, n1*rx2);
0259 cre = rvx*cre;
0260 x{d}=permute(reshape(cre, rnewx, n1, rx2), [2 1 3]);
0261
0262
0263 max_res = 0;
0264 phAold=1; phyold=1;
0265
0266 for i=d:-1:2
0267 a2=A{i}; a1=A{i-1}; ra1=size(a1,3); ra2=size(a1,4); ra3=size(a2,4);
0268 n1 = size(a1,1); m1=size(a1,2); n2=size(a2,1); m2=size(a2,2);
0269 p2=P{i}; p1=P{i-1}; rp1=size(p1,3); rp2=size(p1,4); rp3=size(p2,4);
0270 k1 = size(p1,1); k2=size(p2,1);
0271
0272 y1=y{i-1}; y2=y{i}; ry1=size(y1,2); ry2=size(y1,3); ry3=size(y2,3);
0273 x1=x{i-1}; x2=x{i}; rx1=size(x1,2); rx2=size(x1,3); rx3=size(x2,3);
0274
0275
0276 if (i>2)
0277 rhs1 = phy{i-2};
0278 else
0279 rhs1=1;
0280 end;
0281 rhs1 = reshape(rhs1, rx1*rp1, ry1);
0282 y1 = reshape(permute(y1, [2 1 3]), ry1, n1*ry2);
0283 rhs1 = rhs1*y1;
0284 rhs1 = reshape(rhs1, rx1, rp1, n1, ry2);
0285 rhs1=reshape(permute(rhs1, [1 4 3 2]), rx1*ry2, n1*rp1);
0286 p1 = reshape(permute(p1, [2 3 1 4]), n1*rp1, k1*rp2);
0287 rhs1=rhs1*p1;
0288 rhs1=reshape(rhs1, rx1, ry2, k1, rp2);
0289 rhs1=reshape(permute(rhs1, [1 3 4 2]), rx1*k1, rp2*ry2);
0290
0291 y2=reshape(permute(y2, [2 1 3]), ry2*n2, ry3);
0292 phyold2 = reshape(phyold, rx3*rp3, ry3);
0293 rhs2 = y2*(phyold2.');
0294 rhs2 = reshape(rhs2, ry2, n2, rx3, rp3);
0295 rhs2 = permute(rhs2, [1 3 2 4]);
0296 rhs2 = reshape(rhs2, ry2*rx3, n2*rp3);
0297 p2 = reshape(permute(p2, [2 4 1 3]), n2*rp3, k2*rp2);
0298 rhs2 = rhs2*p2;
0299 rhs2 = reshape(rhs2, ry2, rx3, k2, rp2);
0300 rhs2 = permute(rhs2, [4 1 3 2]);
0301 rhs2 = reshape(rhs2, rp2*ry2, k2*rx3);
0302
0303 if (strcmp(local_format, 'full'))
0304 rhs = rhs1*rhs2;
0305 rhs = reshape(rhs, rx1*k1*k2*rx3, 1);
0306 else
0307 rhs = cell(2,1);
0308 rhs{1} = rhs1;
0309 rhs{2} = rhs2.';
0310 end;
0311
0312 rxn1=rx1; rxn3=rx3;
0313 rxm1=rx1; rxm2=rx2; rxm3=rx3;
0314 if (i>2)
0315 B = phA{i-2};
0316 else
0317 B=1;
0318 end;
0319 B = reshape(B, rxn1, rp1, ra1, rxm1);
0320 B = reshape(permute(B, [1 4 2 3]), rxn1*rxm1*rp1, ra1);
0321 a1 = reshape(permute(A{i-1}, [3 2 1 4]), ra1, m1*n1*ra2);
0322 B = B*a1;
0323 B = reshape(B, rxn1,rxm1,rp1,m1,n1,ra2);
0324 B = permute(B, [1 2 4 6 3 5]);
0325 B = reshape(B, rxn1*rxm1*m1*ra2, rp1*n1);
0326 p1 = reshape(permute(P{i-1}, [3 2 1 4]), rp1*n1, k1*rp2);
0327 B = B*p1;
0328 B = reshape(B, rxn1,rxm1,m1,ra2,k1,rp2);
0329 B = permute(B, [1 5 2 3 6 4]);
0330 B = reshape(B, rxn1*k1*rxm1*m1, rp2*ra2);
0331
0332
0333 B2 = permute(phAold, [1 2 4 3]);
0334 B2 = reshape(B2, rxn3*rp3*rxm3, ra3);
0335 a2 = reshape(A{i}, n2*m2*ra2, ra3);
0336 B2 = B2*(a2.');
0337 B2 = reshape(B2, rxn3, rp3, rxm3, n2, m2, ra2);
0338 B2 = permute(B2, [1 3 5 6 4 2]);
0339 B2 = reshape(B2, rxn3*rxm3*m2*ra2, n2*rp3);
0340 p2 = reshape(permute(P{i}, [2 4 1 3]), n2*rp3, k2*rp2);
0341 B2 = B2*p2;
0342 B2 = reshape(B2, rxn3, rxm3, m2, ra2, k2, rp2);
0343 B2 = permute(B2, [5 1 3 2 6 4]);
0344 B2 = reshape(B2, k2*rxn3*m2*rxm3, rp2*ra2);
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 rB=rp2*ra2;
0365 MatVec='bfun2';
0366 if (((rxn1*k1*k2*rxn3<max_full_size))||(rB>max(rxn1*k1, rxn3*k2)))&&(strcmp(local_format, 'full'))
0367 MatVec='full';
0368 if (rxn1*k1*k2*rxn3>max_full_size)
0369 MatVec='half-full';
0370 end;
0371 B = B*(B2.');
0372 B = reshape(B, rxn1,k1,rxm1,m1,k2,rxn3,m2,rxm3);
0373 B = permute(B, [1 2 5 6 3 4 7 8]);
0374 B = reshape(B, rxn1*k1*k2*rxn3, rxm1*m1*m2*rxm3);
0375 else
0376 B1 = reshape(B, rxn1*k1, rxm1*m1, rB);
0377 B2 = reshape(B2, k2*rxn3, m2*rxm3, rB);
0378 B=cell(2,1);
0379 B{1}=B1;
0380 B{2}=B2;
0381 end;
0382
0383
0384 x1 = reshape(permute(x{i-1}, [2 1 3]), rxm1*m1, rxm2);
0385 x2 = reshape(permute(x{i}, [2 1 3]), rxm2, m2*rxm3);
0386 if (strcmp(local_format, 'full'))
0387 sol_prev = x1*x2;
0388 sol_prev = reshape(sol_prev, rxm1*m1*m2*rxm3, 1);
0389 else
0390 sol_prev = cell(2,1);
0391 sol_prev{1} = x1;
0392 sol_prev{2} = x2.';
0393 end;
0394
0395 real_tol = (tol/(d^dpows(i)))/trunc_to_true;
0396
0397 if (strcmp(local_format, 'tt'))
0398 mv = @(vec,eps,mr)bfun3(B,vec,eps,mr);
0399 else
0400 if (strcmp(MatVec, 'bfun2'))
0401 mv=@(vec)bfun2(B, vec, rxm1,m1,m2,rxm3,rxn1,k1,k2,rxn3);
0402
0403 else
0404 mv = @(vec)(B*vec);
0405
0406 end;
0407 end;
0408
0409
0410 if (strcmp(local_format, 'tt'))
0411 res_prev = mv(sol_prev, [], []);
0412 normf = exp(0.5*tt_dot2(rhs, rhs));
0413 res_prev = tt_dist3(res_prev, rhs)/normf;
0414 else
0415 res_prev = mv(sol_prev);
0416 normf = norm(rhs);
0417 res_prev = norm(res_prev - rhs)/normf;
0418 end;
0419
0420
0421 if (~last_sweep)&&(res_prev>bs_treshold*max_res_old)
0422 if (strcmp(MatVec,'full'))
0423
0424
0425 sol = B \ rhs;
0426
0427 res=B*sol;
0428 res_true = norm(res-rhs)/norm(rhs);
0429 else
0430
0431
0432
0433
0434
0435
0436
0437
0438 if (strcmp(local_format, 'full'))
0439 [sol_new,flg] = gmres(mv, rhs, nrestart, real_tol, 2, [], [], sol_prev);
0440
0441
0442 res_new=norm(mv(sol_new)-rhs)/normf;
0443 conv_factor=(res_new/res_prev);
0444 if (res_new*(conv_factor)>real_tol && use_self_prec && strcmp(MatVec, 'bfun2'))
0445 if (strcmp(local_prec, 'selfprec'))
0446 iB=tt_minres_selfprec(B, prec_tol, prec_compr, prec_iters, 'right');
0447
0448 resid = rhs-mv(sol_new);
0449 [dsol,flg] = gmres(@(vec)bfun2(B, bfun2(iB,vec,rxm1,m1,m2,rxm3,rxn1,k1,k2,rxn3),...
0450 rxm1,m1,m2,rxm3,rxn1,k1,k2,rxn3), resid, nrestart, real_tol/res_new, gmres_iters);
0451 dsol = bfun2(iB,dsol,rxm1,m1,m2,rxm3,rxn1,k1,k2,rxn3);
0452 sol = sol_new+dsol;
0453
0454 end;
0455 if (strcmp(local_prec, 'als'))
0456 sol = als_solve_rx_2(B, rhs, real_tol, [], sol_new);
0457 end;
0458 else
0459 [sol,flg] = gmres(mv, rhs, nrestart, real_tol, gmres_iters, [], [], sol_new);
0460 end;
0461 if (flg>0)
0462 fprintf('-warn- gmres did not converge at block %d\n', i);
0463 end;
0464
0465 res=mv(sol);
0466 res_true = norm(res-rhs)/normf;
0467 else
0468 sol_new = tt_gmres(mv, rhs, real_tol, 2, nrestart, real_tol, real_tol, [], [], [], sol_prev);
0469 res_new=tt_dist3(mv(sol_new,[],[]),rhs)/normf;
0470 conv_factor=(res_new/res_prev);
0471 if (res_new*conv_factor>real_tol && use_self_prec && strcmp(MatVec, 'bfun2'))
0472
0473 iB=tt_minres_selfprec(B, prec_tol, prec_compr, prec_iters, 'right');
0474
0475
0476
0477
0478 sol = tt_gmres(@(vec,eps,mr)bfun3(B, vec, eps, mr), rhs, real_tol, gmres_iters, nrestart, real_tol, real_tol, @(vec,eps,mr)bfun3(iB, vec, eps, mr), [], [], sol_new);
0479
0480
0481
0482
0483 else
0484 sol = tt_gmres(mv, rhs, real_tol, gmres_iters, nrestart, real_tol, real_tol, [], [], [], sol_new);
0485 end;
0486 res=mv(sol,[],[]);
0487 res_true = tt_dist3(res,rhs)/normf;
0488 end;
0489 end;
0490
0491 if (strcmp(local_format, 'full'))
0492 dx(i) = norm(sol-sol_prev,'fro')/norm(sol_prev,'fro');
0493 else
0494 dx(i) = tt_dist3(sol, sol_prev)/exp(0.5*tt_dot2(sol,sol));
0495 end;
0496 else
0497 res_true = res_prev;
0498 dx(i)=0;
0499 sol = sol_prev;
0500 end;
0501
0502 if (verb>1)
0503 fprintf('=dmrg_solve2= Sweep %d, block %d, res_true = %3.3e\n', swp, i, res_true);
0504 end;
0505 if ((res_true>res_prev/trunc_to_true))&&(res_true>real_tol)&&(~last_sweep)
0506 fprintf('--warn-- the residual damp by gmres was smaller than in the truncation\n');
0507
0508 sol = sol_prev;
0509 res_true = res_prev;
0510 end;
0511
0512 if (res_prev>max_res)
0513 max_res = res_prev;
0514 end;
0515
0516 if (verb>1)
0517 fprintf('=dmrg_solve2= Sweep %d, block %d, dx=%3.3e, res_prev = %3.3e\n', swp, i, dx(i), res_prev);
0518 end;
0519 if (strcmp(local_format, 'full'))
0520 nrmsol = norm(sol, 'fro');
0521 else
0522 nrmsol = exp(0.5*tt_dot2(sol,sol));
0523 end
0524 if (nrmsol==0)
0525 dx(i)=0;
0526 end;
0527
0528 if (swp==1)
0529 dx_old(i)=dx(i);
0530 end;
0531
0532
0533 if (dx(i)/dx_old(i)>top_conv)&&(dx(i)>eps/(d^d_pow_check))
0534 drank(i)=drank(i)+ddrank;
0535 dpows(i)=dpows(i)+ddpow;
0536 end;
0537
0538 if (dx(i)/dx_old(i)<bot_conv)||(dx(i)<eps/(d^d_pow_check))
0539 drank(i)=max(drank(i)-ddrank, min_drank);
0540 dpows(i)=max(dpows(i)-ddpow, min_dpow);
0541 end;
0542
0543 if (last_sweep)
0544 dpows(i)=min(0.5, min_dpow);
0545 end;
0546
0547 if (res_prev>bs_treshold*max_res_old)&&(strcmp(local_format, 'full'))
0548 if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0549 [u,s,v]=svd(sol-reshape(sol_prev,[rxm1*m1,m2*rxm3]),'econ');
0550 else
0551 if (~last_sweep)
0552 sol=reshape(sol,[rxm1*m1,m2*rxm3]);
0553 [u,s,v]=svd(sol,'econ');
0554 else
0555 [x2,rv]=qr(x2.', 0);
0556 x1 = x1*(rv.');
0557 [u,s,v]=svd(x1, 'econ');
0558 v = x2*v;
0559 end;
0560 end;
0561 s = diag(s);
0562 flm=norm(s);
0563
0564 r0 = 1; rM = min(size(s,1),rmax); r = round((r0+rM)/2);
0565 while (rM-r0>2)
0566 er0=norm(s(r+1:numel(s)));
0567 if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0568 sol = sol_prev+reshape(u(:,1:r)*diag(s(1:r))*(v(:,1:r))',rxm1*m1*m2*rxm3, 1);
0569 else
0570 sol = reshape(u(:,1:r)*diag(s(1:r))*(v(:,1:r))',rxm1*m1*m2*rxm3, 1);
0571 end;
0572 if (strcmp(MatVec,'full')||strcmp(MatVec,'half-full'))
0573 resid = norm(B*sol-rhs)/norm(rhs);
0574 else
0575 resid = norm(bfun2(B,sol,rxm1,m1,m2,rxm3,rxn1,k1,k2,rxn3)-rhs)/norm(rhs);
0576 end;
0577
0578
0579
0580 if ((resid<max(res_true*trunc_to_true, eps/(d^dpows(i)))) )
0581 rM = r-1;
0582 r = round((r0+rM)/2);
0583 else
0584 r0 = r;
0585 r = round((r0+rM)/2);
0586 end;
0587 end
0588 r = r0;
0589
0590 cursol = cell(2,1);
0591 cursol{1}=u(:,1:r);
0592 cursol{2}=conj(v(:,1:r))*diag(s(1:r));
0593 if (strcmp(MatVec,'full')||strcmp(MatVec,'half-full'))
0594 resid = B*full(tt_tensor(cursol),rxm1*m1*m2*rxm3)-rhs;
0595
0596 else
0597 resid = full(tt_tensor(tt_mv(B,cursol)),rxm1*m1*m2*rxm3)-rhs;
0598
0599 end;
0600 while (r<min(size(s,1), rmax))
0601 r=r+1;
0602 er0=norm(s(r+1:numel(s)));
0603 cursol{1}=u(:,r);
0604 cursol{2}=conj(v(:,r))*s(r);
0605 if (strcmp(MatVec,'full')||strcmp(MatVec,'half-full'))
0606 resid = B*full(tt_tensor(cursol),rxm1*m1*m2*rxm3)+resid;
0607
0608
0609 else
0610 resid = full(tt_tensor(tt_mv(B,cursol)),rxm1*m1*m2*rxm3)+resid;
0611
0612
0613 end;
0614 normres = norm(resid)/norm(rhs);
0615
0616
0617
0618 if ((normres<max(res_true*trunc_to_true, eps/(d^dpows(i)))) )
0619 break;
0620 end;
0621 end;
0622
0623 if (~last_sweep)
0624 r = r+drank(i);
0625 end;
0626
0627 v = conj(v);
0628 else
0629 if (strcmp(local_format, 'tt'))
0630 x1 = sol{1};
0631 x2 = sol{2}.';
0632 end;
0633
0634
0635 [v,rv]=qr(x2.',0);
0636 r = size(v,2);
0637
0638 u = x1*rv.';
0639 s = ones(r,1);
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692 end;
0693 r = min(r, max(size(s)));
0694 r = min(r,rmax);
0695
0696 v = v(:,1:r);
0697 u = u(:,1:r)*diag(s(1:r));
0698
0699 if ( verb>1 )
0700 fprintf('=dmrg_solve2= sweep %d, block %d, r=%d, resid=%g, er0=%g, MatVec=%s, rB=%d\n', swp, i, r, normres, er0/flm, MatVec, rB);
0701 end
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718 if (mod(swp,dropsweeps)~=0)&&(swp>1)&&(~last_sweep)
0719 u = [x1, u];
0720 v = [x2.', v];
0721 [v,rv]=qr(v,0);
0722 u = u*(rv.');
0723 r = size(v,2);
0724 else
0725 if (~last_sweep)
0726 vr=randn(size(v,1),kickrank);
0727 v=reort(v,vr);
0728 radd=size(v,2)-r;
0729 if ( radd > 0 )
0730 ur=zeros(size(u,1),radd);
0731 u=[u,ur];
0732 end
0733 r=r+radd;
0734 end;
0735 end;
0736
0737
0738
0739
0740
0741
0742
0743 x{i}=permute(reshape(v, m2, rxm3, r), [1 3 2]);
0744 x{i-1}=permute(reshape(u, rxm1, m1, r), [2 1 3]);
0745 rxm2=r; rxn2=r;
0746
0747 if (verb>2)
0748
0749 n1 = size(A{1},1);
0750 ra1 = size(A{1},4);
0751 rx1 = size(x{1},3);
0752 ry1 = size(y{1},3);
0753 A{1}=squeeze(A{1});
0754 x{1}=squeeze(x{1});
0755 y{1}=squeeze(y{1});
0756 true_resid = tt_mv(A,x);
0757 true_resid = tt_dist3(true_resid, y)/sqrt(tt_dot(y,y));
0758 fprintf('=dmrg_solve2= Sweep %d, block %d, true_resid: %3.3e\n', swp, i, true_resid);
0759 A{1}=reshape(A{1}, n1, n1, 1, ra1);
0760 x{1}=reshape(x{1}, n1, 1, rx1);
0761 y{1}=reshape(y{1}, n1, 1, ry1);
0762 end;
0763
0764
0765
0766 phAold = reshape(phAold, rxn3*rp3*ra3, rxm3);
0767 x2 = reshape(x{i}, m2*rxm2, rxm3);
0768 phAold = phAold*(x2.');
0769 phAold = reshape(phAold, rxn3, rp3, ra3, m2, rxm2);
0770 phAold = permute(phAold, [1 2 5 4 3]);
0771 phAold = reshape(phAold, rxn3*rp3*rxm2, m2*ra3);
0772 a2 = reshape(permute(A{i}, [2 4 1 3]), m2*ra3, n2*ra2);
0773 phAold=phAold*a2;
0774 phAold=reshape(phAold, rxn3, rp3, rxm2, n2, ra2);
0775 phAold = permute(phAold, [1 3 5 4 2]);
0776 phAold = reshape(phAold, rxn3*rxm2*ra2, n2*rp3);
0777 p2 = reshape(permute(P{i}, [2 4 1 3]), n2*rp3, k2*rp2);
0778 phAold=phAold*p2;
0779 phAold=reshape(phAold, rxn3,rxm2,ra2,k2,rp2);
0780 phAold = permute(phAold, [2 3 5 1 4]);
0781 phAold = reshape(phAold, rxm2*ra2*rp2, rxn3*k2);
0782 x2 = reshape(permute(x{i}, [3 1 2]), rxn3*k2, rxn2);
0783 phAold = phAold*conj(x2);
0784 phAold = permute(reshape(phAold, rxm2, ra2, rp2, rxn2), [4 3 2 1]);
0785
0786 phyold = reshape(phyold, rxn3*rp3, ry3);
0787 y2 = reshape(y{i}, n2*ry2, ry3);
0788 phyold = phyold*(y2.');
0789 phyold = reshape(phyold, rxn3, rp3, n2, ry2);
0790 phyold = permute(phyold, [1 4 3 2]);
0791 phyold = reshape(phyold, rxn3*ry2, n2*rp3);
0792 p2 = reshape(permute(P{i}, [2 4 1 3]), n2*rp3, k2*rp2);
0793 phyold = phyold*p2;
0794 phyold = reshape(phyold, rxn3, ry2, k2, rp2);
0795 phyold = permute(phyold, [4 2 1 3]);
0796 phyold = reshape(phyold, rp2*ry2, rxn3*k2);
0797 x2 = reshape(permute(x{i}, [3 1 2]), rxn3*k2, rxn2);
0798 phyold = phyold*conj(x2);
0799 phyold = permute(reshape(phyold, rp2, ry2, rxn2), [3 1 2]);
0800 end;
0801
0802
0803
0804
0805
0806 max_res_old = max_res;
0807 if (mod(swp,100)==0)
0808 max_res_old = 0;
0809 end;
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826 if (verb>0)
0827 erank=0; sumn=0;
0828 for i=1:d
0829 erank = erank+size(x{i},1)*size(x{i},2)*size(x{i},3);
0830 sumn = sumn+size(x{i},1);
0831 end;
0832 erank = sqrt(erank/sumn);
0833
0834 fprintf('=dmrg_solve2= Sweep %d, dx_max: %3.3e, res_max: %3.3e, erank: %g\n', swp, max(dx), max_res, erank);
0835 end;
0836 if (last_sweep)
0837 break;
0838 end;
0839 if (max_res<tol/(d^d_pow_check))||(swp==nswp-1)
0840 last_sweep=true;
0841
0842 end;
0843
0844 dx_old = dx;
0845
0846
0847
0848
0849
0850
0851
0852
0853 end;
0854
0855 x{1}=reshape(x{1}, size(x{1},1), size(x{1},3));
0856
0857
0858
0859 if (input_is_tt_tensor)
0860 x=tt_tensor(x);
0861 end
0862
0863 if (nargout>1)
0864 sweeps = swp;
0865 end;
0866
0867 end
0868
0869 function [y]=bfun2(B, x, rxm1, m1, m2, rxm3, rxn1, k1, k2, rxn3)
0870
0871
0872
0873 rB=size(B{1},3);
0874 x = reshape(x, rxm1*m1, m2*rxm3);
0875 B1 = permute(B{1}, [3 1 2]);
0876 B1 = reshape(B1, rB*rxn1*k1, rxm1*m1);
0877 y = B1*x;
0878 y = reshape(y, rB, rxn1*k1, m2*rxm3);
0879 y = permute(y, [3 1 2]);
0880 y = reshape(y, m2*rxm3*rB, rxn1*k1);
0881 B2 = reshape(B{2}, k2*rxn3, m2*rxm3*rB);
0882 y = B2*y;
0883 y = reshape(y.', rxn1*k1*k2*rxn3, 1);
0884 end
0885
0886
0887 function [y] = bfun3(A, x, eps, mr)
0888
0889 y = tt_mv(A, x);
0890 if (nargin<4)
0891 mr = [];
0892 end;
0893 if (nargin>2)&&(~isempty(eps))
0894 y = tt_compr2(y, eps, mr);
0895 end;
0896
0897 end
0898