0001 classdef newton_potential < TTeMPS_op_laplace
0002
0003
0004
0005
0006
0007
0008
0009 properties
0010 potential
0011 laplacerank
0012 end
0013
0014 methods( Access = public )
0015
0016 function A = newton_potential( n, d )
0017
0018 one = ones(n,1);
0019 q = linspace( -1, 1, n)';
0020 h = abs(q(2) - q(1));
0021 L = -spdiags( [one, -2*one, one], [-1 0 1], n, n) / (h^2);
0022
0023
0024 A = A@TTeMPS_op_laplace( L, d );
0025 [A.V_L, A.E_L] = eig(full(A.L0));
0026 A.E_L = diag( A.E_L );
0027
0028
0029
0030 a = d*min(q.^2);
0031 b = d*max(q.^2);
0032
0033 k = 10;
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 omega = [0.0122353280385689973405283041685276401722; 0.0170048221567127200615394955196535420328;
0057 0.0292580238127349109583679896348651361393; 0.0513674405142589591607559396796434114663;
0058 0.0876522649954556273282240720645663856203; 0.1452687747918532464746523003018552344656;
0059 0.2347776097665007749814821205736059539504; 0.3716699993620031342879666408363092955369;
0060 0.5822367252037624550361008535226403637353; 0.9561416473224761119619093119315067497155];
0061 alpha = [0.0000278884968834587275257159520245177180; 0.0003161367116046333453815662397571456532;
0062 0.0014174384495922332182950292714732065669; 0.0052598987752533055729865546674972609509;
0063 0.0176506185630681001889793731510214236380; 0.0548279527792261968593219480933020903990;
0064 0.1597705718538013465668734189306654513985; 0.4411611832132119288894626929486975086547;
0065 1.1661865464705391523319785718193486445671; 3.0303805868035630160465393467816852535179];
0066
0067 alpha = alpha/a;
0068 omega = omega/sqrt(a);
0069
0070 C = cell(1, d);
0071
0072 C = exp(-alpha(1)*q.^2);
0073 C = reshape( C, [1 n 1] );
0074 A.potential = omega(1)*TTeMPS( repmat( {C}, [1, d]));
0075 for i = 2:k
0076 C = exp(-alpha(i)*q.^2);
0077 C = reshape( C, [1 n 1] );
0078 A.potential = A.potential + omega(i)*TTeMPS( repmat( {C}, [1, d]));
0079 end
0080
0081 A.laplacerank = A.rank;
0082 A.rank(2:end-1) = A.rank(2:end-1) + A.potential.rank(2:end-1);
0083
0084 end
0085
0086
0087
0088 function y = apply(A, x, idx)
0089
0090 if ~exist( 'idx', 'var' )
0091
0092 A.rank = A.laplacerank;
0093 y = apply@TTeMPS_op_laplace( A, x );
0094 A.rank(2:end-1) = A.rank(2:end-1) + A.potential.rank(2:end-1);
0095
0096
0097
0098 y = y + hadamard( A.potential, x );
0099
0100
0101 else
0102
0103 A.rank = A.laplacerank;
0104 l = apply@TTeMPS_op_laplace( A, x, idx );
0105 A.rank(2:end-1) = A.rank(2:end-1) + A.potential.rank(2:end-1);
0106
0107
0108
0109 h = hadamard( A.potential, x, idx);
0110
0111 if idx == 1
0112 y = zeros( 1, size(l,2), size(l,3)+size(h,3), size(h,4));
0113 y( 1, :, 1:size(l,3), : ) = l;
0114 y( 1, :, size(l,3)+1:end, : ) = h;
0115 elseif idx == A.order
0116 y = zeros( size(l,1)+size(h,1), size(l,2), 1, size(h,4) );
0117 y( 1:size(l,1), :, 1, :) = l;
0118 y( size(l,1)+1:end, :, 1, :) = h;
0119 else
0120 y = zeros( size(l,1)+size(h,1), size(l,2), size(l,3)+size(h,3), size(h,4) );
0121 y( 1:size(l,1), :, 1:size(l,3), : ) = l;
0122 y( size(l,1)+1:end, :, size(l,3)+1:end, : ) = h;
0123 end
0124
0125 end
0126 end
0127
0128
0129
0130
0131
0132 function P = constr_precond( A, k )
0133
0134 d = A.order;
0135 ev = eig(full(A.L0));
0136
0137 lmin = d*min(ev);
0138 lmax = d*max(ev);
0139
0140 R = lmax/lmin;
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 if k == 3
0159 [omega, alpha] = load_coefficients( R );
0160
0161 elseif k == 7
0162 omega = [0.0133615547183825570028305575534521842940 0.0429728469424360175410925952177443321034 0.1143029399081515586560726591147663100401,...
0163 0.2838881266934189482611071431161775535656 0.6622322841999484042811198458711174907876 1.4847175320092703810050463464342840325116,...
0164 3.4859753729916252771962870138366952232900];
0165 alpha = [0.0050213411684266507485648978019454613531 0.0312546410994290844202411500801774835168 0.1045970270084145620410366606112262388706,...
0166 0.2920522758702768403556507270657505159761 0.7407504784499061527671195936939341208927 1.7609744335543204401530945069076494746696,...
0167 4.0759036969145123916954953635638503328664];
0168 else
0169 error('Unknown rank specified. Choose either k=3 or k=7');
0170 end
0171
0172 omega = omega/lmin;
0173 alpha = alpha/lmin;
0174
0175 E = reshape( expm( -alpha(1) * A.L0), [1, A.size_row(d), A.size_col(d), 1]);
0176 P = omega(1)*TTeMPS_op( repmat({E},1,d) );
0177 for i = 2:k
0178 E = reshape( expm( -alpha(i) * A.L0), [1, A.size_row(d), A.size_col(d), 1]);
0179 P = P + omega(i)*TTeMPS_op( repmat({E},1,d) );
0180 end
0181
0182 end
0183
0184 function expB = constr_precond_inner( A, X, mu )
0185
0186
0187
0188
0189
0190 n = size(A.L0, 1);
0191 sz = [X.rank(mu), X.size(mu), X.rank(mu+1)];
0192
0193 B1 = zeros( X.rank(mu) );
0194
0195 for i = 1:mu-1
0196
0197 tmp = X;
0198 Xi = matricize( tmp.U{i}, 2 );
0199 Xi = A.L0*Xi;
0200 tmp.U{i} = tensorize( Xi, 2, [X.rank(i), n, X.rank(i+1)] );
0201 B1 = B1 + innerprod( X, tmp, 'LR', mu-1);
0202 end
0203
0204
0205 B2 = A.L0;
0206
0207 B3 = zeros( X.rank(mu+1) );
0208
0209 for i = mu+1:A.order
0210 tmp = X;
0211 Xi = matricize( tmp.U{i}, 2 );
0212 Xi = A.L0*Xi;
0213 tmp.U{i} = tensorize( Xi, 2, [X.rank(i), n, X.rank(i+1)] );
0214 B3 = B3 + innerprod( X, tmp, 'RL', mu+1);
0215 end
0216
0217 [V1,e1] = eig(B1);
0218 e1 = diag(e1);
0219 [V3,e3] = eig(B3);
0220 e3 = diag(e3);
0221
0222 lmin = min(e1) + min(A.E_L) + min(e3);
0223 lmax = max(e1) + max(A.E_L) + max(e3);
0224
0225 R = lmax/lmin;
0226
0227 [omega, alpha] = load_coefficients( R );
0228
0229 k = length(omega);
0230 omega = omega/lmin;
0231 alpha = alpha/lmin;
0232
0233 expB = cell(3,k);
0234
0235 for i = 1:k
0236 expB{1,i} = omega(i) * V1*diag( exp( -alpha(i)*e1 ))*V1';
0237 expB{2,i} = A.V_L*diag( exp( -alpha(i)*A.E_L ))*A.V_L';
0238 expB{3,i} = V3*diag( exp( -alpha(i)*e3 ))*V3';
0239 end
0240 end
0241
0242 function expB = constr_precond_outer( A, X, mu1, mu2 )
0243
0244
0245
0246
0247
0248 n = size(A.L0, 1);
0249
0250 B1 = zeros( X.rank(mu1) );
0251
0252 for i = 1:mu1-1
0253
0254 tmp = X;
0255 Xi = matricize( tmp.U{i}, 2 );
0256 Xi = A.L0*Xi;
0257 tmp.U{i} = tensorize( Xi, 2, [X.rank(i), n, X.rank(i+1)] );
0258 B1 = B1 + innerprod( X, tmp, 'LR', mu1-1);
0259 end
0260
0261
0262
0263
0264
0265 B3 = zeros( X.rank(mu2+1) );
0266
0267 for i = mu2+1:A.order
0268 tmp = X;
0269 Xi = matricize( tmp.U{i}, 2 );
0270 Xi = A.L0*Xi;
0271 tmp.U{i} = tensorize( Xi, 2, [X.rank(i), n, X.rank(i+1)] );
0272 B3 = B3 + innerprod( X, tmp, 'RL', mu2+1);
0273 end
0274
0275 [V1,e1] = eig(B1);
0276 e1 = diag(e1);
0277 [V3,e3] = eig(B3);
0278 e3 = diag(e3);
0279
0280 lmin = min(e1) + 2*min(A.E_L) + min(e3);
0281 lmax = max(e1) + 2*max(A.E_L) + max(e3);
0282
0283 R = lmax/lmin;
0284
0285 [omega, alpha] = load_coefficients( R );
0286
0287 k = 3;
0288 omega = omega/lmin;
0289 alpha = alpha/lmin;
0290
0291 expB = cell(4,k);
0292
0293 for i = 1:k
0294 expB{1,i} = omega(i) * V1*diag( exp( -alpha(i)*e1 ))*V1';
0295 expB{2,i} = A.V_L*diag( exp( -alpha(i)*A.E_L ))*A.V_L';
0296 expB{3,i} = A.V_L*diag( exp( -alpha(i)*A.E_L ))*A.V_L';
0297 expB{4,i} = V3*diag( exp( -alpha(i)*e3 ))*V3';
0298 end
0299 end
0300
0301 end
0302
0303 end