2 % Copyright (C) 2016 Peter Rakyta, Ph.D.
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.
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.
14 % You should have received a copy of the GNU General Public License
15 % along with
this program. If not, see http:
17 %> @addtogroup basic Basic Functionalities
20 %> @brief Class to regulerize the H1 problem of the leads by SVD decompozition.
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
27 %> EQuUs v4.8 or later
32 properties ( Access =
protected )
33 %>
true if the
Hamiltonians were SVD transformed,
false otherwise
35 %> U matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
37 %> S matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
39 %> V matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
41 %> SVD tolerance to identify singular values
43 %> Somethimes it is needed to perform another SVD cycle to regularize the H1 matrix
45 %> Effective number of
sites after the elimination of the singular values
55 methods ( Access = public )
56 %% constructorof the class
57 %> @brief Constructor of the class.
58 %> @
param Opt An instance of the structure
#Opt. 61 %> @
return An instance of the
class 69 %> @brief Calculates the SVD decomposition of the matrix H1.
70 function obj = SVDdecompozition( obj )
72 [obj.U, obj.S, obj.V] = svd(full(obj.K1));
74 [obj.U, obj.S, obj.V] = svd(obj.K1);
77 obj.U = sparse(obj.U);
78 obj.V = sparse(obj.V);
84 %> @brief Decides whether SVD regularization is needed or not.
85 %> @
return Returns with
true if SVD regularization is needed,
false otherwise
86 function ret = is_SVD_needed(obj)
87 if 1/condest(obj.H1)<obj.tolerance
95 %% Calc_Effective_Hamiltonians
96 %> @brief Calculates the effective
Hamiltonians according to Eq (48) of of PRB 78, 035407
97 %> @
param E The energy value
98 function Calc_Effective_Hamiltonians( obj, E )
100 obj.ApplyOverlapMatrices(E);
102 if ~isempty(obj.kulso_szabfokok) && length(obj.kulso_szabfokok) ~= size(obj.K0,1)
103 obj.Decimate_Hamiltonians();
105 elseif 1/condest(obj.K1)<obj.tolerance && isempty(obj.V)
109 % in
case no SVD regularization or simple decimation is needed
110 obj.Neff = size(obj.K0,1);
118 %% Get_Effective_Hamiltonians
119 %> @brief Gets the effective
Hamiltonians K0_eff, K1_eff, K1adj_eff according to Eq (48) of of PRB 78, 035407
120 %> @
return Returns with the effective
Hamiltonians K0_eff, K1_eff, K1adj_eff
121 function [K0_eff, K1_eff, K1adj_eff] = Get_Effective_Hamiltonians(obj)
122 if isempty(obj.next_SVD_cycle)
125 K1adj_eff = obj.K1adj;
126 elseif strcmpi(
class(obj.next_SVD_cycle),
'SVDregularizationLead' )
127 [K0_eff, K1_eff, K1adj_eff] = obj.next_SVD_cycle.Get_Effective_Hamiltonians();
129 error(
'EQuUs:SVDregularizationLead:Get_Effective_Hamiltonians',
'Unrecognized type of attribute next_SVD_cycle');
134 %% Get_Effective_Overlaps
135 %> @brief Gets the effective
Hamiltonians S0_eff, S1_eff, S1adj_eff according to Eq (48) of of PRB 78, 035407
136 %> @
return Returns with the effective
Hamiltonians S0_eff, S1_eff, S1adj_eff
137 function [S0_eff, S1_eff, S1adj_eff] = Get_Effective_Overlaps(obj)
138 if isempty(obj.next_SVD_cycle)
141 S1adj_eff = obj.S1adj;
142 elseif strcmpi(
class(obj.next_SVD_cycle),
'SVDregularizationLead' )
143 [S0_eff, S1_eff, S1adj_eff] = obj.next_SVD_cycle.Get_Effective_Overlaps();
145 error(
'EQuUs:SVDregularizationLead:Get_Effective_Overlaps',
'Unrecognized type of attribute next_SVD_cycle');
151 %> @brief Regularize the
Hamiltonians of the lead by SVD regularization
152 function SVD_transform( obj )
154 obj.SVDdecompozition();
158 if ~isempty(obj.q) && ~obj.HamiltoniansDecimated
159 K0 = K0 + obj.K1_transverse*diag(exp(1i*obj.q)) + obj.K1_transverse
'*diag(exp(-1i*obj.q)); 162 % Eqs (48) in PRB 78, 035407 163 % here we use diiferent transformation for the leads with diffferent orientation 164 if obj.Lead_Orientation == 1 166 elseif obj.Lead_Orientation == -1 171 K1adj = U'*obj.K1adj*U;
173 obj.Neff = size(obj.K0, 1);
175 % determine singular values
177 regular_sites_slab = transpose(find(S > obj.tolerance*max(S)));
179 K = [K0, K1; K1adj, K0];
182 regular_sites = [regular_sites_slab, size(K0,1)+regular_sites_slab];
185 CreateH.Write(
'Hscatter', K);
186 CreateH.Write(
'kulso_szabfokok', regular_sites);
187 CreateH.Write(
'HamiltoniansCreated',
true);
188 CreateH.Write(
'HamiltoniansDecimated',
false);
191 Decimation_Procedure.DecimationFunc(0, CreateH,
'Hscatter',
'kulso_szabfokok');
193 K = CreateH.Read(
'Hscatter');
194 CreateH.Clear(
'Hscatter');
196 Neff_new = length(regular_sites_slab);
198 if obj.Lead_Orientation == 1
199 K0 = K(Neff_new+1:end, Neff_new+1:end);
200 elseif obj.Lead_Orientation == -1
201 K0 = K(1:Neff_new, 1:Neff_new);
203 K1 = K(1:Neff_new, Neff_new+1:end);
204 K1adj = K(Neff_new+1:end, 1:Neff_new);
208 obj.next_SVD_cycle.Write(
'K0', K0);
209 obj.next_SVD_cycle.Write(
'K1', K1);
210 obj.next_SVD_cycle.Write(
'K1adj', K1adj);
211 obj.next_SVD_cycle.Write(
'OverlapApplied',
true);
212 obj.next_SVD_cycle.Write(
'HamiltoniansDecimated',
true);
213 obj.next_SVD_cycle.Write(
'Neff', Neff_new);
216 obj.is_SVD_transformed =
true;
217 obj.HamiltoniansDecimated =
true;
220 condition_num = 1/condest(K1);
222 condition_num = rcond(K1);
225 if condition_num<obj.tolerance
226 obj.next_SVD_cycle.Calc_Effective_Hamiltonians( 0 );
230 %% Decimate_Interface
232 function Decimate_Hamiltonians( obj )
234 K0loc = obj.K0 + obj.K1_transverse*diag(exp(1i*obj.q)) + obj.K1_transverse
'*diag(exp(-1i*obj.q)); 238 K = [K0loc,obj.K1;obj.K1adj,K0loc]; 240 regular_sites_slab = obj.kulso_szabfokok; 241 regular_sites = [regular_sites_slab, size(obj.K0,1)+regular_sites_slab]; 244 CreateH = CreateHamiltonians(obj.Opt, obj.param); 245 CreateH.Write('Hscatter
', K); 246 CreateH.Write('kulso_szabfokok
', regular_sites); 247 CreateH.Write('HamiltoniansCreated
', true); 248 CreateH.Write('HamiltoniansDecimated
', false); 250 Decimation_Procedure = Decimation(obj.Opt); 251 Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter
', 'kulso_szabfokok
'); 253 K = CreateH.Read('Hscatter
'); 254 CreateH.Clear('Hscatter
'); 256 Neff_new = length(regular_sites_slab); 258 K0 = K(Neff_new+1:end, Neff_new+1:end); 259 K1 = K(1:Neff_new, Neff_new+1:end); 260 K1adj = K(Neff_new+1:end, 1:Neff_new); 262 obj.next_SVD_cycle = SVDregularizationLead(obj.Opt, obj.param, obj.varargin{:}); 263 obj.next_SVD_cycle.Write('K0
', K0); 264 obj.next_SVD_cycle.Write('K1
', K1); 265 obj.next_SVD_cycle.Write('K1adj
', K1adj); 266 obj.next_SVD_cycle.Write('OverlapApplied
', true); 267 obj.next_SVD_cycle.Write('HamiltoniansDecimated
', true); 268 obj.next_SVD_cycle.Write('Neff
', Neff_new); 270 obj.HamiltoniansDecimated = true; 273 % Decimation_Procedure_Lead = Decimation(obj.Opt, 'ForcedDecimation
', obj.Opt.Decimation); 274 % kulso_szabfokok_tmp = obj.kulso_szabfokok; 275 % obj.kulso_szabfokok = [obj.kulso_szabfokok, obj.kulso_szabfokok+size(obj.H0,1)]; 276 % Decimation_Procedure_Lead.DecimationFunc(0, obj, 'Hamiltonian2Dec
', 'kulso_szabfokok
'); 277 % obj.kulso_szabfokok = kulso_szabfokok_tmp; 278 % obj.Neff = size(obj.K0,1); 283 %> @brief Transforms the effective Hamiltonians by a unitary transformation 284 %> @param Umtx The matrix of the unitary transformation. 285 function Unitary_Transform(obj, Umtx) 287 if isempty(obj.next_SVD_cycle) 289 obj.K0 = Umtx*obj.K0*Umtx';
293 obj.K1 = Umtx*obj.K1*Umtx
'; 296 if ~isempty(obj.K1adj) 297 obj.K1adj = Umtx*obj.K1adj*Umtx';
300 elseif strcmpi(
class(obj.next_SVD_cycle),
'SVDregularizationLead' )
301 obj.next_SVD_cycle.Unitary_Transform(Umtx);
303 error(
'EQuUs:SVDregularizationLead:Unitary_Transform',
'Unrecognized type of attribute next_SVD_cycle');
309 %> @brief Gets the effective number of
sites after the elimination of the singular values.
310 %> @
return Returns with the effective number of
sites 311 function Neff = Get_Neff(obj)
312 if isempty(obj.next_SVD_cycle)
314 elseif strcmpi(
class(obj.next_SVD_cycle),
'SVDregularizationLead' )
315 Neff = obj.next_SVD_cycle.Get_Neff();
317 error(
'EQuUs:SVDregularizationLead:Get_Neff',
'Unrecognized type of attribute next_SVD_cycle');
325 %> @brief Gets the total transformation U related to the SVD transformation
326 %> @
return Returns with the total transformation U
327 function Vtot = Get_V(obj)
328 if isempty(obj.next_SVD_cycle)
330 elseif strcmpi(
class(obj.next_SVD_cycle),
'SVDregularizationLead' )
331 Vtot_tmp = obj.next_SVD_cycle.Get_V();
332 size_V = size(obj.V);
333 size_Vtmp = size(Vtot_tmp);
334 Vtot_tmp = [Vtot_tmp, zeros(size_Vtmp(1), size_V(2)-size_Vtmp(2));
335 zeros(size_V(1)-size_Vtmp(1), size_Vtmp(2)), eye(size_V(1)-size_Vtmp(1))];
336 Vtot = obj.V*Vtot_tmp;
338 error(
'EQuUs:SVDregularizationLead:Get_V',
'Unrecognized type of attribute next_SVD_cycle');
344 %> @brief Creates a clone of the present
object.
345 %> @
return Returns with the cloned
object.
346 %> @
param varargin Cell array of optional parameters:.
347 function ret = CreateClone( obj, varargin )
350 p.addParameter(
'empty',
false );
352 p.parse(varargin{:});
353 empty = p.Results.empty;
356 'Hanyadik_Lead', obj.Hanyadik_Lead,...
357 'Lead_Orientation', obj.Lead_Orientation, ...
364 meta_data = metaclass(obj);
366 for idx = 1:length(meta_data.PropertyList)
367 prop_name = meta_data.PropertyList(idx).Name;
368 if strcmpi( prop_name,
'next_SVD_cycle' )
369 if ~isempty( obj.next_SVD_cycle )
370 ret.next_SVD_cycle = obj.next_SVD_cycle.CreateClone();
373 ret.Write( prop_name, obj.(prop_name));
381 %> @brief Resets all elements in the
object.
382 function Reset( obj )
384 if strcmp(
class(obj),
'SVDregularizationLead' )
385 meta_data = metaclass(obj);
387 for idx = 1:length(meta_data.PropertyList)
388 prop_name = meta_data.PropertyList(idx).Name;
389 if strcmp(prop_name,
'Opt') || strcmp( prop_name,
'param') || strcmp(prop_name,
'varargin')
392 obj.Clear( prop_name );
403 %> @brief Sets the value of an attribute in the interface.
404 %> @
param MemberName The name of the attribute to be
set.
405 %> @
param input The value to be
set.
406 function Write(obj, MemberName, input)
409 if strcmp(MemberName,
'param') || strcmp(MemberName,
'params')
414 obj.(MemberName) = input;
416 error([
'EQuUs:',
class(obj),
':Read'], [
'No property to write with name: ', MemberName]);
422 %> @brief Query
for the value of an attribute in the interface.
423 %> @
param MemberName The name of the attribute to be
set.
424 %> @
return Returns with the value of the attribute.
425 function ret = Read(obj, MemberName)
427 if strcmp(MemberName,
'Hamiltonian2Dec')
428 ret = Read@CreateLeadHamiltonians( obj, MemberName );
432 ret = obj.(MemberName);
434 error([
'EQuUs:',
class(obj),
':Read'], [
'No property to read with name: ', MemberName]);
440 %> @brief Clears the value of an attribute in the interface.
441 %> @
param MemberName The name of the attribute to be cleared.
442 function Clear(obj, MemberName)
445 obj.(MemberName) = [];
447 error([
'EQuUs:',
class(obj),
':Clear'], [
'No property to clear with name: ', MemberName]);
457 methods (Access=
protected)
460 %% Extend_Wavefnc ---- DEVELOPMENT
461 %> @brief Extend a reduced wave
function to the original basis before the SVD regularization (Eq (45) in PRB 78 035407
462 %> @
param wavefnc_reduced The reduced wavefunction of the effective system
463 %> @
param expk e^(i*k)
464 function wavefnc_extended = Extend_Wavefnc(obj, wavefnc_reduced, expk)
466 if ~isempty(obj.next_SVD_cycle) && strcmpi(
class(obj.next_SVD_cycle),
'SVDregularizationLead' )
467 wavefnc_reduced = obj.next_SVD_cycle.Extend_Wavefnc(wavefnc_reduced, expk);
468 elseif ~isempty(obj.next_SVD_cycle)
469 error(
'EQuUs:SVDregularizationLead:Extend_Wavefnc',
'Unrecognized type of attribute next_SVD_cycle');
472 Fn = -obj.invD*(obj.K1adju/expk + obj.C);
473 wavefnc_extended = [wavefnc_reduced; Fn*wavefnc_reduced];
474 wavefnc_extended = obj.U*wavefnc_extended;
481 %> @brief Initializes
object properties.
482 function Initialize(obj)
483 Initialize@CreateLeadHamiltonians(obj);
484 obj.tolerance = 1e-12;
485 obj.is_SVD_transformed =
false;
491 end % methods
protected Structure Opt contains the basic computational parameters used in EQuUs.
Class to create and store Hamiltonian of the translational invariant leads.
function Transport(Energy, B)
creating the Ribbon class representing the twoterminal setup
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...
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 ...
Structure sites contains data to identify the individual sites in a matrix.
Class to solve the eigenproblem of a translational invariant leads and calculate the group velocities...
A class to create and store Hamiltonian of the scattering region.