Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
Decimation.m
Go to the documentation of this file.
1 %% Eotvos Quantum Transport Utilities - Decimation
2 % Copyright (C) 2009-2015 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 %
18 %> @addtogroup basic Basic Functionalities
19 %> @{
20 %> @file Decimation.m
21 %> @brief A class providing function handle to reduce the number of sites in the Hamiltonian via decimation procedure.
22 %> @}
23 %> @brief A class providing function handle to reduce the number of sites in the Hamiltonian via decimation procedure.
24 %> The Decimation parameter in structure #Opt picks the following decimation procedures \n
25 %> Opt.Decimation=1 or Opt.Decimation=2 picks procedure #decimation_1_and_2 \n
26 %> Opt.Decimation=3 picks procedure #decimation_3 \n
27 %> Opt.Decimation=4 picks procedure #decimation_4 \n
28 %%
30 
31 
32  properties ( Access = public )
33 %> The function handle of the decimation method
34  DecimationFunc
35  end
36 
37 methods ( Access = public )
38 %% Contructor of the class
39 %> @brief Constructor of the class.
40 %> @param Opt An instance of the structure #Opt.
41 %> @param varargin Cell array of optional parameters:
42 %> @param 'ForcedDecimation' Overrides the parameter value Opt.Decimation in structure #Opt.
43 %> @return An instance of the class
44  function obj = Decimation( Opt, varargin)
45  obj = obj@Messages( Opt );
46 
47  p = inputParser;
48  p.addParameter('ForcedDecimation', []);
49  p.parse(varargin{:});
50 
51  ForcedDecimation = p.Results.ForcedDecimation;
52 
53  if ~isempty(ForcedDecimation)
54  obj.Opt.Decimation = ForcedDecimation;
55  end
56 
57  if isempty( Opt.Decimation )
58  error(['EQuUs:', class(obj), ':Decimation:Wrong_Decimation_Parameter'], 'Empty Decimation parameter given in Opt.Decimation.')
59  end
60 
61 
62  if Opt.Decimation == 3
63  obj.DecimationFunc = @(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites)(obj.decimation_3(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites));
64  elseif Opt.Decimation == 4
65  obj.DecimationFunc = @( E, Way2Hamiltonian, NameOfH, NameOfRegular_sites )(obj.decimation_4(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites ));
66  elseif Opt.Decimation == 1 || Opt.Decimation == 2
67  obj.DecimationFunc = @(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites)(obj.decimation_1_and_2(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites));
68  else
69  warning(['EQuUs:', class(obj), ':Decimation:Wrong_Decimation_Parameter'], 'Wrong Decimation parameter given! Using default 4.')
70  obj.DecimationFunc = @(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites)(obj.decimation_4(E, Way2Hamiltonian, NameOfH, NameOfRegular_sites));
71  end
72 
73  end
74 
75 %% decimation_4
76 %> @brief Algorithm to reduce the number of the sites in the Hamiltonian via decimation. The number of the decimated sites in one turn varies dynamically in order to avoid badly conditioned matrices. Equally fast as #decimation_3, but more stable and more accurate.
77 %> @param E The energy value
78 %> @param Way2Hamiltonian An instance of class CreateHamiltonians (or a derived class).
79 %> @param NameOfH Name of the attribute storing the Hamiltonian to be decimate (typically use 'Hscatter')
80 %> @param NameOfRegular_sites Name of the attribute storing the idexes of sites to be kept after the decimation. (typically use 'kulso_szabfokok')
81  function decimation_4(obj, E, Way2Hamiltonian, NameOfH, NameOfRegular_sites )
82 
83  if Way2Hamiltonian.Read('HamiltoniansDecimated')
84  obj.display(['EQuUs:', class(obj), ':decimation_4: The Hamiltonian is already decimated'],1);
85  return
86  elseif ~Way2Hamiltonian.Read('HamiltoniansCreated')
87  obj.display(['EQuUs:', class(obj), ':decimation_4: The Hamiltonian needs to be created before the decimation'],1);
88  return
89  end
90 
91  %blokk_size_max = 50;
92  blokk_size_max = obj.Opt.Decimation_block;
93 
94  Hamiltoni = Way2Hamiltonian.Read( NameOfH );
95  regular_sites = Way2Hamiltonian.Read( NameOfRegular_sites );
96 
97  if length(regular_sites) >= size(Hamiltoni,1)
98  obj.display(['EQuUs:', class(obj), ':decimation_4: Nothing to be decimated']);
99  return
100  end
101 
102  Way2Hamiltonian.Clear( NameOfH );
103 
104  sorting_sites();
105  blocks = blocks_to_be_decimated();
106 
107  for idx = length(blocks):-1:2
108  decimation_of_block2( blocks(idx)-blocks(idx-1) );
109  end
110 
111 
112  Way2Hamiltonian.Write( NameOfH, Hamiltoni );
113  Way2Hamiltonian.Write('HamiltoniansDecimated', true)
114 
115 
116 
117  %-----------------------------------------------------------------
118  % nested functions
119 
120  %------------------------------------------------------------------
121  % determines the blocks of the Hamiltonian to be decimated out
122  function blocks = blocks_to_be_decimated()
123  blocks = length(regular_sites):blokk_size_max:size(Hamiltoni,1);
124  if blocks(end) < size(Hamiltoni,1)
125  blocks(end+1) = size(Hamiltoni,1);
126  end
127 
128  if length(blocks) < 2
129  error(['EQuUs:', class(obj), ':decimation_4'], 'Error in determining the blocks to be decimated');
130  end
131  end
132 
133 
134  %------------------------------------------------------------------
135  % sites to be decimated out are sorted to the end
136  function sorting_sites()
137  indexes = false( size(Hamiltoni,1), 1);
138  indexes(regular_sites) = true;
139 
140  Hamiltoni = [Hamiltoni(indexes,indexes), Hamiltoni(indexes,~indexes);
141  Hamiltoni(~indexes,indexes), Hamiltoni(~indexes,~indexes)];
142 
143 
144  regular_sites = 1:length(regular_sites);
145 
146 
147  end
148 
149 
150  %------------------------------------------------------------------
151  % decimates out the given block in the Hamiltonian
152  function decimation_of_block2( num )
153 
154  while num > 0
155 
156  nevezo = E*eye(num) - Hamiltoni(end-num+1:end, end-num+1:end);
157  if issparse(nevezo)
158  cond_number = rcond(full(nevezo));
159  else
160  cond_number = rcond(nevezo);
161  end
162  tolerance = 1e-4;
163 
164  %if abs(cond_number-1) > tolerance
165  if cond_number < tolerance && num > 1
166  num2 = increase_condition_number();
167  decimation_of_block2( num2 );
168  num = num - num2;
169  else
170  % here the given block with good condition number is
171  % decimated out
172  [~, col_idx] = find( Hamiltoni(end-num+1:end, 1:end-num) );
173  col_blocks = unique(floor(col_idx/blokk_size_max));
174  for jdx = 1:length(col_blocks)
175  col_min = max( [col_blocks(jdx)*blokk_size_max, 1] );
176  col_max = min( [size(Hamiltoni,2)-num, (col_blocks(jdx)+1)*blokk_size_max-1] );
177  cols = col_min:col_max;
178  H_21 = Hamiltoni( end-num+1:end, cols);
179  nevezo2 = nevezo\H_21;
180 
181  [row_idx2, ~] = find( Hamiltoni(1:end-num, end-num+1:end) );
182  row_blocks = unique(floor(row_idx2/blokk_size_max));
183  for kdx = 1:length(row_blocks)
184  row_min = max( [row_blocks(kdx)*blokk_size_max, 1] );
185  row_max = min( [size(Hamiltoni,1)-num, (row_blocks(kdx)+1)*blokk_size_max-1] );
186  rows = row_min:row_max;
187  H_12 = Hamiltoni( rows, end-num+1:end );
188  H_11 = H_12*nevezo2;
189 
190  if issparse(Hamiltoni)
191  size_H = size(Hamiltoni,1);
192 
193  [rows_H11, cols_H11, elements_H11] = find(H_11);
194  if size(H_11,1) == 1
195  rows_H11 = transpose(rows_H11);
196  cols_H11 = transpose(cols_H11);
197  elements_H11 = transpose(elements_H11);
198  end
199  rows_H11 = rows_H11 + row_min - 1 ;
200  cols_H11 = cols_H11 + col_min - 1;
201 
202  [rows_H, cols_H, elements] = find( Hamiltoni );
203  Hamiltoni = [];
204  Hamiltoni = sparse( [rows_H; rows_H11], [cols_H; cols_H11], [elements; elements_H11], size_H, size_H );
205  else
206  Hamiltoni(rows, cols) = Hamiltoni( rows, cols ) + H_11;
207  end
208 
209  end
210 
211  end
212 
213  % delete the decimated sites from the Hamiltonian
214  if issparse(Hamiltoni)
215  size_H = size(Hamiltoni,1);
216  [rows, cols, elements] = find( Hamiltoni(1:end-num, 1:end-num) );
217  Hamiltoni = sparse( rows, cols, elements, size_H-num, size_H-num );
218  else
219  Hamiltoni(:, end-num+1:end ) = [];
220  Hamiltoni(end-num+1:end, :) = [];
221  end
222 
223 
224  % convert to full matrix if sparse is not memory
225  % efficient anymore
226  whos_H = whos('Hamiltoni');
227  if whos_H.size(1)*whos_H.size(2)*16 <= whos_H.bytes && whos_H.sparse == 1
228  Hamiltoni = full(Hamiltoni);
229  obj.display(['EQuUs:', class(obj), 'Sparse Hamiltonian was converted to full.']);
230  end
231 
232 
233  num = 0;
234 
235  end
236  end
237 
238 
239 
240  %-----------------------------------
241  % determine block size for which the matrix can be inverted
242  function num_tmp = increase_condition_number()
243  num_tmp = num;
244  while cond_number < tolerance
245  num_tmp = floor(num_tmp/2);
246  if num_tmp == 1
247  break
248  end
249  nevezo = E*eye(num_tmp) - Hamiltoni(end-num_tmp+1:end, end-num_tmp+1:end);
250  if issparse(nevezo)
251  cond_number = rcond(full(nevezo));
252  else
253  cond_number = rcond(nevezo);
254  end
255  end
256 
257  nevezo = [];
258  end
259 
260  end
261 
262  %-----------------------------------------------------------------
263  % end nested functions
264 
265 
266  end
267 
268 %% decimation_3
269 %> @brief Algorithm to reduce the number of the sites in the Hamiltonian via decimation. The number of the decimated sites in one turn varies dynamically in order to avoid badly conditioned matrices.
270 %> @param E The energy value
271 %> @param Way2Hamiltonian An instance of class CreateHamiltonians (or a derived class).
272 %> @param NameOfH Name of the attribute storing the Hamiltonian to be decimate (typically use 'Hscatter')
273 %> @param NameOfRegular_sites Name of the attribute storing the idexes of sites to be kept after the decimation. (typically use 'kulso_szabfokok')
274  function decimation_3(obj, E, Way2Hamiltonian, NameOfH, NameOfRegular_sites )
275 
276  if Way2Hamiltonian.Read('HamiltoniansDecimated')
277  obj.display(['EQuUs:', class(obj), ':decimation_3: The Hamiltonian is already decimated'],1);
278  return
279  elseif ~Way2Hamiltonian.Read('HamiltoniansCreated')
280  obj.display(['EQuUs:', class(obj), ':decimation_3: The Hamiltonian needs to be created before the decimation'],1);
281  return
282  end
283 
284  %blokk_size_max = 50;
285  blokk_size_max = obj.Opt.Decimation_block;
286 
287  Hamiltoni = Way2Hamiltonian.Read( NameOfH );
288  regular_sites = Way2Hamiltonian.Read( NameOfRegular_sites );
289  Way2Hamiltonian.Clear( NameOfRegular_sites );
290 
291  obj.setCoordinates( Way2Hamiltonian, regular_sites );
292 
293  megmaradt_szabfokok = sites_after_decimation(regular_sites);
294  Way2Hamiltonian.Write( NameOfRegular_sites, megmaradt_szabfokok );
295 
296  Way2Hamiltonian.Clear( NameOfH );
297 
298  H_size = size(Hamiltoni ,1);
299  blokkok = indexing_of_regular_sites();
300  belso_szabfokok = find(blokkok{2} == 'b');
301 
302  whos_H = whos('Hamiltoni');
303  if whos_H.size(1)*whos_H.size(2)*16 <= whos_H.bytes && whos_H.sparse == 1
304  Hamiltoni = full(Hamiltoni);
305  obj.display('A Hamltoni mar nem ritka');
306  end
307 
308  Idx = length(belso_szabfokok);
309  iidx = 1;
310 
311  while iidx <= Idx
312  idx = belso_szabfokok(iidx);
313  decimation_of_block();
314 
315  whos_H = whos('Hamiltoni');
316  if whos_H.size(1)*whos_H.size(2)*16 <= whos_H.bytes && whos_H.sparse == 1
317  Hamiltoni = full(Hamiltoni);
318  obj.display('A Hamltoni mar nem ritka');
319  end
320 
321  iidx = iidx + 1;
322  end
323 
324 
325 
326  Way2Hamiltonian.Write( NameOfH, Hamiltoni );
327  Way2Hamiltonian.Write('HamiltoniansDecimated', 1)
328 
329  %-----------------------------------------------------------------
330  % nested functions
331 
332  %------------------------------------------------------------------
333  function decimation_of_block()
334 
335  oszlop = [sum(blokkok{1}(1:idx-1))+1,sum(blokkok{1}(1:idx))];
336  nevezo = E*eye(blokkok{1}(idx)) - Hamiltoni(oszlop(1):oszlop(2),oszlop(1):oszlop(2));
337  cond_number = rcond(nevezo);
338  tolerance = 1e-4;
339 
340  %if abs(cond_number-1) > tolerance
341  if cond_number < tolerance
342  clear('nevezo');
343  [oszlop, nevezo] = increase_condition_number();
344  end
345 
346  if cond_number < tolerance
347  obj.display(num2str(cond(nevezo)) )
348  end
349 
350  [sor_idx,oszlop_idx] = find(Hamiltoni(oszlop(1):oszlop(2),:));
351  oszlop_szamok = oszlop_szamolo(oszlop_idx', oszlop, blokk_size_max);
352  Kdx = size(oszlop_szamok,1);
353  kdx = 1;
354  while kdx <= Kdx
355  oszlop_k = oszlop_szamok(kdx,:);
356  jdx = 1;
357  H_darab21 = Hamiltoni(oszlop(1):oszlop(2),oszlop_k(1):oszlop_k(2));
358  nevezo2 = nevezo\H_darab21;
359  while jdx <= Kdx
360  oszlop_j = oszlop_szamok(jdx,:);
361  H_darab11 = Hamiltoni(oszlop_j(1):oszlop_j(2),oszlop_k(1):oszlop_k(2));
362  H_darab12 = Hamiltoni(oszlop_j(1):oszlop_j(2),oszlop(1):oszlop(2));
363  H_darab11 = H_darab11 + H_darab12*nevezo2;
364 
365  Hamiltoni(oszlop_j(1):oszlop_j(2),oszlop_k(1):oszlop_k(2)) = H_darab11;
366  jdx = jdx + 1;
367  end
368  kdx = kdx + 1;
369  end
370 
371  if issparse(Hamiltoni)
372  [sor_idx,oszlop_idx,elemek] = find(Hamiltoni);
373  Hamiltoni = [];
374  indexek = logical(((oszlop(1)<=sor_idx) & (sor_idx <=oszlop(2))) | ((oszlop(1)<=oszlop_idx) & (oszlop_idx <=oszlop(2))));
375  sor_idx(indexek) = [];
376  oszlop_idx(indexek) = [];
377  elemek(indexek) = [];
378  indexek = logical(sor_idx>oszlop(2));
379  sor_idx(indexek) = sor_idx(indexek) - blokkok{1}(idx);
380  indexek = logical(oszlop_idx>oszlop(2));
381  oszlop_idx(indexek) = oszlop_idx(indexek) - blokkok{1}(idx);
382  clear indexek;
383  blokkok{1}(idx) = [];
384  blokkok{2}(idx) = [];
385  Hamiltoni = sparse(sor_idx,oszlop_idx,elemek,sum(blokkok{1}),sum(blokkok{1}));
386  clear sor_idx oszlop_idx elemek;
387  else
388  Hamiltoni(oszlop(1):oszlop(2),:) = [];
389  Hamiltoni(:,oszlop(1):oszlop(2)) = [];
390  blokkok{1}(idx) = [];
391  blokkok{2}(idx) = [];
392 
393  end
394  belso_szabfokok = belso_szabfokok -1;
395 
396 
397  %------------------------------------------------------------------
398  % kiszamolja hogy a kidecimalando szabfokokat hogy kell beoszlopozni
399  function oszlop_szamok = oszlop_szamolo(oszlop_idx, oszlop_decimalo, blokk_size_max)
400 
401  blokk_size_max = 150*blokk_size_max;
402  ldx = 1;
403  Ldx = length(oszlop_idx);
404 
405  if oszlop_idx(1) >= oszlop_decimalo(1)
406  while oszlop_idx(ldx) <= oszlop_decimalo(2)
407  ldx = ldx + 1;
408  end
409  oszlop_szamok = [oszlop_idx(ldx),oszlop_idx(ldx)];
410  else
411  oszlop_szamok = [oszlop_idx(1),oszlop_idx(1)];
412  end
413 
414  ldx = ldx + 1;
415 
416  while (ldx <= Ldx) && (oszlop_decimalo(1) > oszlop_idx(ldx))
417  if (oszlop_idx(ldx)-oszlop_szamok(end,1) > blokk_size_max)
418  oszlop_szamok(end,2) = oszlop_idx(ldx-1);
419  oszlop_szamok = [oszlop_szamok;[oszlop_idx(ldx),oszlop_idx(ldx)]];
420  end
421  ldx = ldx + 1;
422  end
423 
424  oszlop_szamok(end,2) = oszlop_idx(ldx-1);
425 
426  while (ldx < Ldx) && (oszlop_decimalo(2) > oszlop_idx(ldx))
427  ldx = ldx + 1;
428  end
429 
430  oszlop_szamok = [oszlop_szamok;[oszlop_idx(ldx),oszlop_idx(ldx)]];
431 
432  while ldx <= Ldx
433  if (oszlop_idx(ldx)-oszlop_szamok(end,1) > blokk_size_max)
434  oszlop_szamok(end,2) = oszlop_idx(ldx-1);
435  oszlop_szamok = [oszlop_szamok;[oszlop_idx(ldx),oszlop_idx(ldx)]];
436  end
437  ldx = ldx + 1;
438  end
439 
440  oszlop_szamok(end,2) = oszlop_idx(ldx-1);
441  %oszlop_szamok = [1,oszlop_decimalo(1)-1;oszlop_decimalo(2)+1,H_size];
442 
443  end
444  %------------------------------------------------------------------
445 
446 
447  %------------------------------------------------------------------
448  function [oszlop,nevezo] = increase_condition_number()
449 
450  %display(['condition number = ',num2str(cond_number)]);
451  blokkok{1} = [blokkok{1}(1:idx);blokkok{1}(idx:end)];
452  blokkok{2} = [blokkok{2}(1:idx);blokkok{2}(idx:end)];
453  egyik_fele = blokkok{2}(idx);
454  blokkok{1}(idx+1) = 0;
455 
456  %while abs(cond_number-1) >= tolerance && egyik_fele >= 2
457  while cond_number <= tolerance && egyik_fele >= 2
458  egyik_fele = round(blokkok{1}(idx)*2.99/4);
459  masik_fele = blokkok{1}(idx) - egyik_fele;
460  blokkok{1}(idx) = egyik_fele;
461  blokkok{1}(idx+1) = masik_fele + blokkok{1}(idx+1);
462  oszlop = [sum(blokkok{1}(1:idx-1))+1,sum(blokkok{1}(1:idx))];
463  nevezo = E*eye(blokkok{1}(idx)) - Hamiltoni(oszlop(1):oszlop(2),oszlop(1):oszlop(2));
464  cond_number = rcond(nevezo);
465  end
466  %display(num2str(blokkok{1}(idx)))
467  %display(['atjavitott condition number = ',num2str(cond_number),' valamint kidecimalando szabfokok = ',num2str(blokkok{1}(idx))]);
468  belso_szabfokok = [belso_szabfokok(1:iidx);belso_szabfokok(iidx:end)];
469  belso_szabfokok(iidx+1:end) = belso_szabfokok(iidx+1:end) + 1;
470  Idx = length(belso_szabfokok);
471 
472 
473 
474  end
475  %------------------------------------------------------------------
476 
477 
478  end
479  %------------------------------------------------------------------
480 
481 
482  %------------------------------------------------------------------
483  % Determines the blocks of regular sites.
484  function blokkok = indexing_of_regular_sites()
485 
486 
487  regular_sites = sort(regular_sites);
488  iii_max = length(regular_sites);
489  iiidx = 1;
490  blokkok = cell(2,1);
491 
492  while iiidx <= iii_max
493 
494  szabfok_tipus = [];
495  blokk_size = 1;
496  if (sum(blokkok{1}) + blokk_size) == regular_sites(iiidx)
497  while (iiidx == iii_max || regular_sites(iiidx+1) == regular_sites(iiidx)+1) && blokk_size <= blokk_size_max
498  blokk_size = blokk_size + 1;
499  iiidx = iiidx + 1;
500  if iiidx >= iii_max; blokk_size = blokk_size-1; break; end
501  end
502  if blokk_size == 1 && iiidx < iii_max ; iiidx = iiidx + 1; end
503  szabfok_tipus = 'k'; % kulso szabfok
504  elseif (sum(blokkok{1}) + blokk_size) < regular_sites(iiidx)
505  while (sum(blokkok{1}) + blokk_size + 1 < regular_sites(iiidx)) && blokk_size <= blokk_size_max
506  blokk_size = blokk_size + 1;
507  end
508  szabfok_tipus = 'b'; % kidecimalando belso szabfokok
509  elseif isempty(szabfok_tipus) && (sum(blokkok{1}) + blokk_size) > regular_sites(iiidx)
510  iiidx = iiidx + 1;
511  szabfok_tipus = [];
512  blokk_size = [];
513  end
514 
515  blokkok{1} = [blokkok{1};blokk_size];
516  blokkok{2} = [blokkok{2};szabfok_tipus];
517 
518 
519  end
520 
521  szabfokok = H_size-sum(blokkok{1});
522 
523  if szabfokok > 0
524  blokk_size_max = blokk_size_max + 1;
525  blokkok_kieg = ones((szabfokok-mod(szabfokok,blokk_size_max))/blokk_size_max,1)*blokk_size_max;
526  szabfok_tipus_kieg = char(ones((szabfokok-mod(szabfokok,blokk_size_max))/blokk_size_max,1)*'b');
527  blokkok{1} = [blokkok{1};blokkok_kieg;mod(szabfokok,blokk_size_max)];
528  blokkok{2} = [blokkok{2};szabfok_tipus_kieg;'b'];
529  end
530 
531  end
532  %------------------------------------------------------------------
533 
534 
535  %------------------------------------------------------------------
536  % Determines the sites after decimation
537  function remaining_sites = sites_after_decimation(regular_sites)
538 
539  L = length(regular_sites);
540  idx = 1;
541  ertek_temp = [];
542  Maximum = max(regular_sites);
543  remaining_sites = zeros(L,1);
544  while idx <= L
545  szabfok_max = max(remaining_sites);
546  [ertek,index] = min(regular_sites);
547  if ertek_temp == ertek
548  remaining_sites(index) = szabfok_max;
549  else
550  ertek_temp = ertek;
551  remaining_sites(index) = szabfok_max+1;
552  end
553  regular_sites(index) = Maximum+1;
554  idx = idx + 1;
555  end
556 
557 
558 
559  end
560 
561  % end nested functions
562  %------------------------------------------------------------------
563 
564 
565 
566  end
567 
568 %% decimation_1_and_2
569 %> @brief Algorithm to reduce the number of sites in the Hamiltonian via decimation. The number of the decimated sites is fixed during the calculations.
570 %> @param E The energy value
571 %> @param Way2Hamiltonian An instance of class CreateHamiltonians (or a derived class).
572 %> @param NameOfH Name of the attribute storing the Hamiltonian to be decimate (typically use 'Hscatter')
573 %> @param NameOfRegular_sites Name of the attribute storing the idexes of sites to be kept after the decimation (typically use 'kulso_szabfokok').
574 function decimation_1_and_2(obj, E, Way2Hamiltonian, NameOfH, NameOfRegular_sites )
575 
576  if Way2Hamiltonian.Read('HamiltoniansDecimated')
577  obj.display(['EQuUs:', class(obj), ':decimation_1_and_2: The Hamiltonian is already decimated'],1);
578  return
579  elseif ~Way2Hamiltonian.Read('HamiltoniansCreated')
580  obj.display(['EQuUs:', class(obj), ':decimation_1_and_2: The Hamiltonian needs to be created before the decimation'],1);
581  return
582  end
583 
584  Hamiltoni = Way2Hamiltonian.Read( NameOfH );
585  regular_sites = Way2Hamiltonian.Read( NameOfRegular_sites );
586  Way2Hamiltonian.Clear( NameOfH );
587  Way2Hamiltonian.Clear( NameOfRegular_sites );
588 
589  obj.setCoordinates( Way2Hamiltonian, regular_sites );
590 
591  Idx = size(Hamiltoni, 1);
592  idx = 1;
593  [minidx,minkoord] = min(regular_sites);
594  minidxtemp = 0;
595  szabfokok_szama = length(regular_sites);
596  megmaradt_szabfokok = zeros(szabfokok_szama,1);
597 
598 
599 
600  while idx <= Idx
601 
602  if idx < minidx
603  if obj.Opt.Decimation == 1
604  sitewise_decimation;
605  regular_sites = regular_sites - 1;
606  minidx = minidx - 1;
607  Idx = size(Hamiltoni, 1);
608  elseif obj.Opt.Decimation == 2
609  blokk_size_max = obj.Opt.Decimation_block;
610  blokk_size = minidx - idx;
611  if blokk_size > blokk_size_max
612  blokk_size = blokk_size_max;
613  end
614  decimalas_blokkonkent(blokk_size);
615  s = whos('Hamiltoni');
616  if s.size(1)*s.size(2)*16 <= s.bytes && s.sparse == 1
617  Hamiltoni = full(Hamiltoni);
618  else
619  Hamiltoni = sparse(Hamiltoni);
620  end
621  regular_sites = regular_sites - blokk_size;
622  minidx = minidx - blokk_size;
623  Idx = size(Hamiltoni, 1);
624  else
625  error(['EQuUs:', class(obj), ':decimation_1_and_2'], 'Wrong decimation parameter: Opt_Decimation');
626  end
627 
628  else
629  if minidx ~= minidxtemp
630  idx = idx + 1;
631  end
632 
633  if minidx <= Idx
634  megmaradt_szabfokok(minkoord) = idx-1;
635  regular_sites(minkoord) = Idx+1;
636  end
637  minidxtemp = minidx;
638  [minidx,minkoord] = min(regular_sites);
639  end
640 
641 
642  end
643 
644  if megmaradt_szabfokok(minkoord) == 0
645  megmaradt_szabfokok(minkoord) = minidx;
646  end
647 
648  Way2Hamiltonian.Write( NameOfH, Hamiltoni );
649  Way2Hamiltonian.Write( NameOfRegular_sites, megmaradt_szabfokok );
650  Way2Hamiltonian.Write( 'HamiltoniansDecimated', 1 );
651 
652 
653  %-----------------------------------------------------------------
654  % nested functions
655 
656  %------------------------------------------------------------------
657  function decimalas_blokkonkent(blokk_size)
658 
659 
660  Hsize = Idx;
661 
662  E_matrix = eye(blokk_size)*E;
663 
664  if idx == 1
665  Hamiltoni = Hamiltoni(blokk_size+1:Hsize,blokk_size+1:Hsize) + ...
666  Hamiltoni(blokk_size+1:Hsize,1:blokk_size) /(E_matrix-Hamiltoni(1:blokk_size,1:blokk_size) * Hamiltoni(1:blokk_size,blokk_size+1:Hsize));
667 
668  elseif idx+blokk_size-1 == Hsize
669 
670  Hamiltoni = Hamiltoni(1:Hsize-blokk_size,1:Hsize-blokk_size) + ...
671  Hamiltoni(1:Hsize-blokk_size,Hsize-blokk_size+1:Hsize) /(E_matrix-Hamiltoni(Hsize-blokk_size+1:Hsize,Hsize-blokk_size+1:Hsize)) * Hamiltoni(Hsize-blokk_size+1:Hsize,1:Hsize-blokk_size);
672 
673  else
674  blokk_size = blokk_size-1;
675  nevezo = (E_matrix-Hamiltoni(idx:idx+blokk_size,idx:idx+blokk_size))\eye(size(E_matrix));
676  Hdeci11 = Hamiltoni(1:idx-1,1:idx-1) + Hamiltoni(1:idx-1,idx:idx+blokk_size)*nevezo*Hamiltoni(idx:idx+blokk_size,1:idx-1);
677  Hdeci12 = Hamiltoni(1:idx-1,idx+blokk_size+1:Hsize) + Hamiltoni(1:idx-1,idx:idx+blokk_size)*nevezo*Hamiltoni(idx:idx+blokk_size,idx+blokk_size+1:Hsize);
678  Hdeci21 = Hamiltoni(idx+blokk_size+1:Hsize,1:idx-1) + Hamiltoni(idx+blokk_size+1:Hsize,idx:idx+blokk_size)*nevezo*Hamiltoni(idx:idx+blokk_size,1:idx-1);
679  Hdeci22 = Hamiltoni(idx+blokk_size+1:Hsize,idx+blokk_size+1:Hsize) + Hamiltoni(idx+blokk_size+1:Hsize,idx:idx+blokk_size)*nevezo*Hamiltoni(idx:idx+blokk_size,idx+blokk_size+1:Hsize);
680  Hamiltoni = [];
681  Hamiltoni = [Hdeci11,Hdeci12;Hdeci21,Hdeci22];
682  end
683 
684  end
685  %------------------------------------------------------------------
686 
687 
688  %------------------------------------------------------------------
689  % decimalas pontonkent
690  function sitewise_decimation()
691 
692 
693 
694 
695  nem_nulla_idx = find(Hamiltoni(:,idx));
696  rekurzioszam = max(size(nem_nulla_idx));
697 
698  sor = 1;
699  while sor <= rekurzioszam
700 
701  if ~(nem_nulla_idx(sor) == idx)
702  oszlop = 1;
703  while oszlop <= rekurzioszam
704  if nem_nulla_idx(oszlop) == idx
705  oszlop = oszlop + 1;
706  else
707  Hamiltoni(nem_nulla_idx(sor),nem_nulla_idx(oszlop)) = Hamiltoni(nem_nulla_idx(sor),nem_nulla_idx(oszlop)) + ...
708  Hamiltoni(nem_nulla_idx(sor),idx)*Hamiltoni(idx,nem_nulla_idx(oszlop)) / (E-Hamiltoni(idx,idx));
709  oszlop = oszlop + 1;
710  end
711  end
712  end
713  sor = sor + 1;
714  end
715  Hamiltoni(idx,:) = [];
716  Hamiltoni(:,idx) = [];
717 
718  end
719  %------------------------------------------------------------------
720 
721  % end nested functions
722 
723 end
724 
725 end % methods public
726 
727 methods ( Access = protected )
728 %% setCoordinates
729 %> @brief Sets the coordinates of the remaining sites after the decimation is finshed.
730 %> @param Way2Hamiltonian An instance of class CreateHamiltonians (or a derived class).
731 %> @param regular_sites Array of idexes of sites kept after the decimation
732  function setCoordinates( obj, Way2Hamiltonian, regular_sites )
733 
734  coordinates = Way2Hamiltonian.Read( 'coordinates' );
735 
736  if isempty(coordinates)
737  obj.display(['EQuUs:', class(obj), ':setCoordinates: structure coordinates is empty!'])
738  return
739  end
740 
741  indexes = logical( regular_sites <= length(coordinates.x) );
742 
743  coordinates.x = coordinates.x(regular_sites(indexes));
744  coordinates.y = coordinates.y(regular_sites(indexes));
745 
746  if isprop( coordinates, 'spinup' ) && ~isempty( coordinates.spinup )
747  coordinates.spinup = coordinates.spinup(regular_sites(indexes));
748  end
749 
750  if isprop( coordinates, 'BdG_u' ) && ~isempty( coordinates.BdG_u )
751  coordinates.BdG_u = coordinates.BdG_u(regular_sites(indexes));
752  end
753 
754  Way2Hamiltonian.Write('coordinates', coordinates );
755 
756  end
757 
758 end %methods protected
759 
760 end % Global end
761 
762 
763 
764 
765 
766 
Property HamiltoniansCreated
A logical value. True if the Hamiltonian was created, false otherwise.
A class containing methodes for displaying several standard messages.
Definition: Messages.m:24
function Write(MemberName, input)
Sets the value of an attribute in the class.
Structure Opt contains the basic computational parameters used in EQuUs.
Definition: structures.m:60
function display(message, nosilent)
Displays output messages on the screen.
Property coordinates
An instance of the structure coordinates.
function Transport(Energy, B)
Calculates the conductance at a given energy value.
A class providing function handle to reduce the number of sites in the Hamiltonian via decimation pro...
Definition: Decimation.m:29
Property kulso_szabfokok
A list of the sites to be kept after decimation.
function Clear(MemberName)
Clears the value of an attribute in the class.
function()
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
Property Hscatter
The matrix of the Hamiltonian.
Decimation
Option for using decimation algorith. (see more details at the documenatation of class Decimation)
Definition: structures.m:88
Property HamiltoniansDecimated
A logical value. True if the Hamiltonian was decimated, or false otherwise.
function Read(MemberName)
Query for the value of an attribute in the class.
A class to create and store Hamiltonian of the scattering region.