Eötvös Quantum Utilities  v5.0.144
Providing the Horsepowers in the Quantum Realm
SVDregularizationLead.m
Go to the documentation of this file.
1 %% Eotvos Quantum Transport Utilities - SVDregularizationLead
2 % Copyright (C) 2016 Peter Rakyta, Ph.D.
3 %
4 % This program is free software: you can redistribute it and/or modify
5 % it under the terms of the GNU General Public License as published by
6 % the Free Software Foundation, either version 3 of the License, or
7 % (at your option) any later version.
8 %
9 % This program is distributed in the hope that it will be useful,
10 % but WITHOUT ANY WARRANTY; without even the implied warranty of
11 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 % GNU General Public License for more details.
13 %
14 % You should have received a copy of the GNU General Public License
15 % along with this program. If not, see http://www.gnu.org/licenses/.
16 %
17 %> @addtogroup basic Basic Functionalities
18 %> @{
19 %> @file SVDregularizationLead.m
20 %> @brief Class to regulerize the H1 problem of the leads by SVD decompozition.
21 %> @}
22 %> @brief Class to regulerize the H1 problem of the leads by SVD decompozition.
23 %> The notations and the structure of the Hamiltonian is defined accroding to the following image:
24 %> @image html Lead_Hamiltonian.jpg
25 %> @image latex Lead_Hamiltonian.jpg
26 %> @Available
27 %> EQuUs v4.8 or later
28 %%
30 
31 
32 properties ( Access = protected )
33  %> true if the Hamiltonians were SVD transformed, false otherwise
34  is_SVD_transformed
35  %> U matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
36  U
37  %> S matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
38  S
39  %> V matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
40  V
41  %> SVD tolerance to identify singular values
42  tolerance
43  %> Somethimes it is needed to perform another SVD cycle to regularize the H1 matrix
44  next_SVD_cycle
45  %> Effective number of sites after the elimination of the singular values
46  Neff
47 
48 
49 end
50 
51 
52 
53 
54 
55 methods ( Access = public )
56 %% constructorof the class
57 %> @brief Constructor of the class.
58 %> @param Opt An instance of the structure #Opt.
59 %> @param param An instance of structure #param.
60 %> @param varargin Cell array of optional parameters identical to #CreateLeadHamiltonians.CreateLeadHamiltonians.
61 %> @return An instance of the class
62  function obj = SVDregularizationLead(Opt, param, varargin)
63  obj = obj@CreateLeadHamiltonians( Opt, param, varargin{:} );
64  end
65 
66 
67 
68 %% SVDdecompozition
69 %> @brief Calculates the SVD decomposition of the matrix H1
70 %> @param The transverse momentum dependent coulping between the unit cell (K1 is transverse momentum dependent, only if skew coupling #H1_skew_right or #H1_skew_left and the transverse momentum #q are not empty).
71  function SVDdecompozition( obj, K1 )
72  if issparse(K1)
73  [obj.U, obj.S, obj.V] = svd(full(K1));
74  else
75  [obj.U, obj.S, obj.V] = svd(K1);
76  end
77 
78  obj.U = sparse(obj.U);
79  obj.V = sparse(obj.V);
80 
81  obj.S = diag(obj.S);
82  end
83 
84 %% is_SVD_needed
85 %> @brief Decides whether SVD regularization is needed or not.
86 %> @return Returns with true if SVD regularization is needed, false otherwise
87  function ret = is_SVD_needed(obj)
88  if 1/condest(obj.H1)<obj.tolerance
89  ret = true;
90  else
91  ret = false;
92  end
93  end
94 
95 
96 %% Calc_Effective_Hamiltonians
97 %> @brief Calculates the effective Hamiltonians according to Eq (48) of of PRB 78, 035407
98 %> @param E The energy value
99  function Calc_Effective_Hamiltonians( obj, E )
100 
101  obj.ApplyOverlapMatrices(E);
102 
103  if ~isempty(obj.kulso_szabfokok) && length(obj.kulso_szabfokok) ~= size(obj.K0,1)
104  obj.Decimate_Hamiltonians();
105  return
106  elseif 1/condest(obj.K1)<obj.tolerance && isempty(obj.V)
107  obj.SVD_transform();
108  return
109  else
110  % in case no SVD regularization or simple decimation is needed
111  obj.Neff = size(obj.K0,1);
112  return
113  end
114 
115 
116  end
117 
118 
119 %% Get_Effective_Hamiltonians
120 %> @brief Gets the effective Hamiltonians K0_eff, K1_eff, K1adj_eff according to Eq (48) of of PRB 78, 035407
121 %> @return [1] The effective Hamiltonian of one unit cell
122 %> @return [2] The effective coupling between unit cells K1_eff
123 %> @return [3] The adjungate of the effective coupling between unit cells K1adj_eff
124  function [K0_eff, K1_eff, K1adj_eff] = Get_Effective_Hamiltonians(obj)
125  if isempty(obj.next_SVD_cycle)
126  [K0_eff, K1_eff, K1adj_eff] = obj.qDependentHamiltonians();
127  elseif strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
128  [K0_eff, K1_eff, K1adj_eff] = obj.next_SVD_cycle.Get_Effective_Hamiltonians();
129  else
130  error('EQuUs:SVDregularizationLead:Get_Effective_Hamiltonians', 'Unrecognized type of attribute next_SVD_cycle');
131  end
132 
133  end
134 
135 %% Get_Effective_Overlaps
136 %> @brief Gets the effective Hamiltonians S0_eff, S1_eff, S1adj_eff according to Eq (48) of of PRB 78, 035407
137 %> @return [1] The effective overlap matrix of one unit cell S0_eff
138 %> @return [2] The effective overlap matrix between unit cells S1_eff
139 %> @return [3] The adjungate of the effective overlap matrix between unit cells S1adj_eff
140  function [S0_eff, S1_eff, S1adj_eff] = Get_Effective_Overlaps(obj)
141  if isempty(obj.next_SVD_cycle)
142  [S0_eff, S1_eff, S1adj_eff] = obj.qDependentOverlaps();
143  elseif strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
144  [S0_eff, S1_eff, S1adj_eff] = obj.next_SVD_cycle.Get_Effective_Overlaps();
145  else
146  error('EQuUs:SVDregularizationLead:Get_Effective_Overlaps', 'Unrecognized type of attribute next_SVD_cycle');
147  end
148 
149  end
150 
151 %% Get_Effective_Coordinates
152 %> @brief Gets the coordinates of the sites of the effective Hamiltonians. (Has sense if the singular sites were given directly)
153 %> @return [1] A class Coordinates containing the coordinates of the sites of the effective Hamiltonian
154  function coordinates = Get_Effective_Coordinates(obj)
155  if isempty(obj.next_SVD_cycle)
156  coordinates = obj.coordinates;
157  elseif strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
158  coordinates = obj.next_SVD_cycle.Get_Effective_Coordinates();
159  else
160  error('EQuUs:SVDregularizationLead:Get_Effective_Coordinates', 'Unrecognized type of attribute next_SVD_cycle');
161  end
162 
163  end
164 
165 
166 %% SVD_transform
167 %> @brief Regularize the Hamiltonians of the lead by SVD regularization
168  function SVD_transform( obj )
169 
170  % determine the Hamiltonians K0 and K1, K1adj used in transport calculations
171  [K0, K1, K1adj] = obj.qDependentHamiltonians();
172 
173  obj.SVDdecompozition( K1 );
174 
175  % Eqs (48) in PRB 78, 035407
176  % here we use diiferent transformation for the leads with diffferent orientation
177  if obj.Lead_Orientation == 1
178  U = obj.V;
179  elseif obj.Lead_Orientation == -1
180  U = obj.U;
181  end
182  K0 = U'*K0*U;
183  K1 = U'*K1*U;
184  K1adj = U'*K1adj*U;
185 
186  obj.Neff = size(obj.K0, 1);
187 
188  % determine singular values
189  S = abs(obj.S);
190  regular_sites_slab = transpose(find(S > obj.tolerance*max(S)));
191 
192  K = [K0, K1; K1adj, K0];
193 
194 
195  regular_sites = [regular_sites_slab, size(K0,1)+regular_sites_slab];
196 
197  CreateH = CreateHamiltonians(obj.Opt, obj.param);
198  CreateH.Write('Hscatter', K);
199  CreateH.Write('kulso_szabfokok', regular_sites);
200  CreateH.Write('HamiltoniansCreated', true);
201  CreateH.Write('HamiltoniansDecimated', false);
202 
203  Decimation_Procedure = Decimation(obj.Opt);
204  Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
205 
206  K = CreateH.Read('Hscatter');
207  CreateH.Clear('Hscatter');
208 
209  Neff_new = length(regular_sites_slab);
210 
211  if obj.Lead_Orientation == 1
212  K0 = K(Neff_new+1:end, Neff_new+1:end);
213  elseif obj.Lead_Orientation == -1
214  K0 = K(1:Neff_new, 1:Neff_new);
215  end
216  K1 = K(1:Neff_new, Neff_new+1:end);
217  K1adj = K(Neff_new+1:end, 1:Neff_new);
218 
219 
220  obj.next_SVD_cycle = SVDregularizationLead(obj.Opt, obj.param, obj.varargin{:});
221  obj.next_SVD_cycle.Write('K0', K0);
222  obj.next_SVD_cycle.Write('K1', K1);
223  obj.next_SVD_cycle.Write('K1adj', K1adj);
224  obj.next_SVD_cycle.Write('OverlapApplied', true);
225  obj.next_SVD_cycle.Write('HamiltoniansDecimated', true);
226  obj.next_SVD_cycle.Write('Neff', Neff_new);
227 
228 
229  obj.is_SVD_transformed = true;
230  obj.HamiltoniansDecimated = true;
231 
232  if issparse(K1)
233  condition_num = 1/condest(K1);
234  else
235  condition_num = rcond(K1);
236  end
237 
238  if condition_num<obj.tolerance
239  obj.next_SVD_cycle.Calc_Effective_Hamiltonians( 0 );
240  end
241  end
242 
243 %% Decimate_Hamiltonians
244 %> @brief Decimates the Hamiltonians (if the singular sites are predefined).
245  function Decimate_Hamiltonians( obj )
246  % determine the Hamiltonians K0 and K1, K1adj used in transport calculations
247  [K0loc, K1loc, K1adjloc] = obj.qDependentHamiltonians();
248 
249  K = [K0loc, K1loc;
250  K1adjloc, K0loc];
251 
252  regular_sites_slab = obj.kulso_szabfokok;
253  regular_sites = [regular_sites_slab, size(obj.K0,1)+regular_sites_slab];
254 
255 
256  CreateH = CreateHamiltonians(obj.Opt, obj.param);
257  CreateH.Write('Hscatter', K);
258  CreateH.Write('kulso_szabfokok', regular_sites);
259  CreateH.Write('HamiltoniansCreated', true);
260  CreateH.Write('HamiltoniansDecimated', false);
261 
262  Decimation_Procedure = Decimation(obj.Opt);
263  Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
264 
265  K = CreateH.Read('Hscatter');
266  CreateH.Clear('Hscatter');
267  coordinates = CreateH.Read('coordinates');
268 
269  Neff_new = length(regular_sites_slab);
270 
271  K0 = K(Neff_new+1:end, Neff_new+1:end);
272  K1 = K(1:Neff_new, Neff_new+1:end);
273  K1adj = K(Neff_new+1:end, 1:Neff_new);
274 
275  obj.next_SVD_cycle = SVDregularizationLead(obj.Opt, obj.param, obj.varargin{:});
276  obj.next_SVD_cycle.Write('K0', K0);
277  obj.next_SVD_cycle.Write('K1', K1);
278  obj.next_SVD_cycle.Write('K1adj', K1adj);
279  obj.next_SVD_cycle.Write('OverlapApplied', true);
280  obj.next_SVD_cycle.Write('HamiltoniansDecimated', true);
281  obj.next_SVD_cycle.Write('Neff', Neff_new);
282 
283 
284  obj.HamiltoniansDecimated = true;
285 
286 
287  % determine the truncated coordinates
288  indexes2remove = true( size( obj.coordinates.x ) );
289  indexes2remove( regular_sites_slab ) = false;
290  coordinates = obj.coordinates.RemoveSites( indexes2remove );
291  obj.next_SVD_cycle.Write('coordinates', coordinates);
292 
293 
294 
295 % Decimation_Procedure_Lead = Decimation(obj.Opt, 'ForcedDecimation', obj.Opt.Decimation);
296 % kulso_szabfokok_tmp = obj.kulso_szabfokok;
297 % obj.kulso_szabfokok = [obj.kulso_szabfokok, obj.kulso_szabfokok+size(obj.H0,1)];
298 % Decimation_Procedure_Lead.DecimationFunc(0, obj, 'Hamiltonian2Dec', 'kulso_szabfokok');
299 % obj.kulso_szabfokok = kulso_szabfokok_tmp;
300 % obj.Neff = size(obj.K0,1);
301 
302  end
303 
304 %% Unitary_Transform
305 %> @brief Transforms the effective Hamiltonians by a unitary transformation
306 %> @param Umtx The matrix of the unitary transformation.
307  function Unitary_Transform(obj, Umtx)
308 
309  if isempty(obj.next_SVD_cycle)
310  if ~isempty(obj.K0)
311  obj.K0 = Umtx*obj.K0*Umtx';
312  end
313 
314  if ~isempty(obj.K1)
315  obj.K1 = Umtx*obj.K1*Umtx';
316  end
317 
318  if ~isempty(obj.K1adj)
319  obj.K1adj = Umtx*obj.K1adj*Umtx';
320  end
321 
322  elseif strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
323  obj.next_SVD_cycle.Unitary_Transform(Umtx);
324  else
325  error('EQuUs:SVDregularizationLead:Unitary_Transform', 'Unrecognized type of attribute next_SVD_cycle');
326  end
327 
328  end
329 
330 %% Get_Neff
331 %> @brief Gets the effective number of sites after the elimination of the singular values.
332 %> @return Returns with the effective number of sites
333  function Neff = Get_Neff(obj)
334  if isempty(obj.next_SVD_cycle)
335  Neff = obj.Neff;
336  elseif strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
337  Neff = obj.next_SVD_cycle.Get_Neff();
338  else
339  error('EQuUs:SVDregularizationLead:Get_Neff', 'Unrecognized type of attribute next_SVD_cycle');
340  end
341  end
342 
343 
344 
345 
346 %% Get_U
347 %> @brief Gets the total transformation U related to the SVD transformation
348 %> @return Returns with the total transformation U
349 function Vtot = Get_V(obj)
350  if isempty(obj.next_SVD_cycle)
351  Vtot = obj.V;
352  elseif strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
353  Vtot_tmp = obj.next_SVD_cycle.Get_V();
354  size_V = size(obj.V);
355  size_Vtmp = size(Vtot_tmp);
356  Vtot_tmp = [Vtot_tmp, zeros(size_Vtmp(1), size_V(2)-size_Vtmp(2));
357  zeros(size_V(1)-size_Vtmp(1), size_Vtmp(2)), eye(size_V(1)-size_Vtmp(1))];
358  Vtot = obj.V*Vtot_tmp;
359  else
360  error('EQuUs:SVDregularizationLead:Get_V', 'Unrecognized type of attribute next_SVD_cycle');
361  end
362 
363 end
364 
365 %% CreateClone
366 %> @brief Creates a clone of the present object.
367 %> @return Returns with the cloned object.
368 %> @param varargin Cell array of optional parameters (https://www.mathworks.com/help/matlab/ref/varargin.html):
369 %> @param 'empty' Set true to create an empty clone, or false (default) to clone all atributes.
370 %> @return Returns with the cloned object.
371  function ret = CreateClone( obj, varargin )
372 
373  p = inputParser;
374  p.addParameter('empty', false );
375 
376  p.parse(varargin{:});
377  empty = p.Results.empty;
378 
379  ret = SVDregularizationLead(obj.Opt, obj.param,...
380  'Hanyadik_Lead', obj.Hanyadik_Lead,...
381  'Lead_Orientation', obj.Lead_Orientation, ...
382  'q', obj.q);
383 
384  if empty
385  return
386  end
387 
388  meta_data = metaclass(obj);
389 
390  for idx = 1:length(meta_data.PropertyList)
391  prop_name = meta_data.PropertyList(idx).Name;
392  if strcmpi( prop_name, 'next_SVD_cycle' )
393  if ~isempty( obj.next_SVD_cycle )
394  ret.next_SVD_cycle = obj.next_SVD_cycle.CreateClone();
395  end
396  else
397  ret.Write( prop_name, obj.(prop_name));
398  end
399  end
400 
401  end
402 
403 
404 %% Reset
405 %> @brief Resets all elements in the object.
406  function Reset( obj )
407 
408  if strcmpi( class(obj), 'SVDregularizationLead' )
409  meta_data = metaclass(obj);
410 
411  for idx = 1:length(meta_data.PropertyList)
412  prop_name = meta_data.PropertyList(idx).Name;
413  if strcmp(prop_name, 'Opt') || strcmp( prop_name, 'param') || strcmp(prop_name, 'varargin')
414  continue
415  end
416  obj.Clear( prop_name );
417  end
418  end
419 
420  obj.Initialize()
421 
422 
423  end
424 
425 
426 %% Write
427 %> @brief Sets the value of an attribute in the interface.
428 %> @param MemberName The name of the attribute to be set.
429 %> @param input The value to be set.
430  function Write(obj, MemberName, input)
431 
432 
433  if strcmpi(MemberName, 'param') || strcmp(MemberName, 'params')
434  Write@CreateLeadHamiltonians( obj, MemberName, input );
435  return
436  else
437  try
438  obj.(MemberName) = input;
439  catch
440  error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
441  end
442  end
443 
444  end
445 %% Read
446 %> @brief Query for the value of an attribute in the interface.
447 %> @param MemberName The name of the attribute to be set.
448 %> @return Returns with the value of the attribute.
449  function ret = Read(obj, MemberName)
450 
451  if strcmpi(MemberName, 'Hamiltonian2Dec')
452  ret = Read@CreateLeadHamiltonians( obj, MemberName );
453  return
454  else
455  try
456  ret = obj.(MemberName);
457  catch
458  error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
459  end
460  end
461 
462  end
463 %% Clear
464 %> @brief Clears the value of an attribute in the interface.
465 %> @param MemberName The name of the attribute to be cleared.
466  function Clear(obj, MemberName)
467 
468  try
469  obj.(MemberName) = [];
470  catch
471  error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
472  end
473 
474  end
475 
476 
477 end % methods public
478 
479 
480 
481 methods (Access=protected)
482 
483 
484 %% Extend_Wavefnc ---- DEVELOPMENT
485 %> @brief Extend a reduced wave function to the original basis before the SVD regularization (Eq (45) in PRB 78 035407
486 %> @param wavefnc_reduced The reduced wavefunction of the effective system
487 %> @param expk e^(i*k)
488 %> @return A matrix conatining the extended wave functions.
489  function wavefnc_extended = Extend_Wavefnc(obj, wavefnc_reduced, expk)
490 
491  if ~isempty(obj.next_SVD_cycle) && strcmpi( class(obj.next_SVD_cycle), 'SVDregularizationLead' )
492  wavefnc_reduced = obj.next_SVD_cycle.Extend_Wavefnc(wavefnc_reduced, expk);
493  elseif ~isempty(obj.next_SVD_cycle)
494  error('EQuUs:SVDregularizationLead:Extend_Wavefnc', 'Unrecognized type of attribute next_SVD_cycle');
495  end
496 
497  Fn = -obj.invD*(obj.K1adju/expk + obj.C);
498  wavefnc_extended = [wavefnc_reduced; Fn*wavefnc_reduced];
499  wavefnc_extended = obj.U*wavefnc_extended;
500 
501  end
502 
503 
504 
505 %% Initialize
506 %> @brief Initializes class properties.
507  function Initialize(obj)
508  Initialize@CreateLeadHamiltonians(obj);
509  obj.tolerance = 1e-12;
510  obj.is_SVD_transformed = false;
511  end
512 
513 
514 
515 
516 end % methods protected
517 
518 
519 
520 
521 
522 end
Property next_SVD_cycle
Somethimes it is needed to perform another SVD cycle to regularize the H1 matrix.
Structure Opt contains the basic computational parameters used in EQuUs.
Definition: structures.m:60
Class to create and store Hamiltonian of the translational invariant leads.
function Transport(Energy, B)
Calculates the conductance at a given energy value.
function Hamiltonians(varargin)
Function to create the custom Hamiltonians for the 1D chain.
A class providing function handle to reduce the number of sites in the Hamiltonian via decimation pro...
Definition: Decimation.m:29
Class to regulerize the H1 problem of the leads by SVD decompozition.
function CreateLeadHamiltonians(Opt, param, varargin)
Constructor of the class.
Structure param contains data structures describing the physical parameters of the scattering center ...
Definition: structures.m:45
Structure sites contains data to identify the individual sites in a matrix.
Definition: structures.m:187
Structure containing the coordinates and other quantum number identifiers of the sites in the Hamilto...
Definition: Coordinates.m:24
A class to create and store Hamiltonian of the scattering region.