├── DMRG ├── DMRG_1ES_1site.m ├── DMRG_GS_1site.m ├── DMRG_GS_2site.m ├── DMRG_GS_CBE.m ├── TDVP_1site.m ├── TDVP_2site.m ├── XTRG.m ├── finT_puri.m ├── iTEBD_GS_Hastings.m ├── iTEBD_GS_Vidal.m ├── mtimes_MPO.m ├── ortho_Orus.m ├── tDMRG.m └── varE_2site.m ├── ML └── ML_MPS.m ├── NRG ├── DMFT_Hubbard.m ├── NRG_IterDiag.m ├── SEtrick.m ├── doCLD.m ├── getAcont.m ├── getAdisc.m ├── getRhoFDM.m └── getTDconv.m ├── PEPS ├── SimpleUp_Honeycomb.m ├── TRG_GILT_Square.m ├── TRG_Honeycomb.m ├── contPlaq.m ├── contract_finPEPS.m └── symCTMRG.m ├── README.md ├── Tensor ├── canonForm.m ├── contract.m ├── getIdentity.m ├── getLocalSpace.m ├── svdTr.m └── updateLeft.m ├── Tutorials ├── T01.1_MATLAB101 │ ├── MATLAB101.m │ ├── MATLAB101.mlx │ └── MATLAB101.pdf ├── T01.2_TightBinding │ ├── TightBinding.m │ ├── TightBinding.mlx │ └── TightBinding.pdf ├── T01.2_TightBinding_sol │ ├── TightBinding_sol.m │ ├── TightBinding_sol.mlx │ └── TightBinding_sol.pdf ├── T01.3_SVD_Example │ ├── Gwanghwamun.jpg │ ├── SVD_Example.m │ ├── SVD_Example.mlx │ └── SVD_Example.pdf ├── T01.3_SVD_Example_sol │ ├── SVD_Example_sol.m │ ├── SVD_Example_sol.mlx │ └── SVD_Example_sol.pdf ├── T02.1_Wstate │ ├── Wstate.m │ ├── Wstate.mlx │ └── Wstate.pdf ├── T02.1_Wstate_sol │ ├── Wstate_sol.m │ ├── Wstate_sol.mlx │ └── Wstate_sol.pdf ├── T02.2_TensorContraction │ ├── TensorContraction.m │ ├── TensorContraction.mlx │ └── TensorContraction.pdf ├── T02.2_TensorContraction_sol │ ├── TensorContraction_sol.m │ ├── TensorContraction_sol.mlx │ └── TensorContraction_sol.pdf ├── T03.1_TensorDecomposition │ ├── TensorDecomposition.m │ ├── TensorDecomposition.mlx │ └── TensorDecomposition.pdf ├── T03.1_TensorDecomposition_sol │ ├── TensorDecomposition_sol.m │ ├── TensorDecomposition_sol.mlx │ └── TensorDecomposition_sol.pdf ├── T04.1_DiagHamiltonian │ ├── DiagHamiltonian.m │ ├── DiagHamiltonian.mlx │ └── DiagHamiltonian.pdf ├── T04.1_DiagHamiltonian_sol │ ├── DiagHamiltonian_sol.m │ ├── DiagHamiltonian_sol.mlx │ └── DiagHamiltonian_sol.pdf ├── T05.1_IterativeDiag │ ├── IterativeDiag.m │ ├── IterativeDiag.mlx │ └── IterativeDiag.pdf ├── T05.1_IterativeDiag_sol │ ├── IterativeDiag_sol.m │ ├── IterativeDiag_sol.mlx │ └── IterativeDiag_sol.pdf ├── T05.2_CanonicalForm │ ├── CanonicalForm.m │ ├── CanonicalForm.mlx │ ├── CanonicalForm.pdf │ └── canonForm_Ex.m ├── T05.2_CanonicalForm_sol │ ├── CanonicalForm_sol.m │ ├── CanonicalForm_sol.mlx │ └── CanonicalForm_sol.pdf ├── T06.1_AKLT │ ├── AKLT.pdf │ └── AKLT.tex ├── T06.1_AKLT_sol │ ├── AKLT_sol.pdf │ └── AKLT_sol.tex ├── T06.2_ExpValues_AKLT │ ├── ExpValues_AKLT.m │ ├── ExpValues_AKLT.mlx │ └── ExpValues_AKLT.pdf ├── T06.2_ExpValues_AKLT_sol │ ├── ExpValues_AKLT_sol.m │ ├── ExpValues_AKLT_sol.mlx │ └── ExpValues_AKLT_sol.pdf ├── T07.1_MPO_MPS │ ├── MPO_MPS.m │ ├── MPO_MPS.mlx │ └── MPO_MPS.pdf ├── T07.1_MPO_MPS_sol │ ├── MPO_MPS_sol.m │ ├── MPO_MPS_sol.mlx │ └── MPO_MPS_sol.pdf ├── T08.1_DMRG_GroundState_1site │ ├── DMRG_GS_1site_Ex.m │ ├── DMRG_GroundState_1site.m │ ├── DMRG_GroundState_1site.mlx │ └── DMRG_GroundState_1site.pdf ├── T08.1_DMRG_GroundState_1site_sol │ ├── DMRG_GroundState_1site_sol.m │ ├── DMRG_GroundState_1site_sol.mlx │ └── DMRG_GroundState_1site_sol.pdf ├── T09.1_DMRG_ExcitedState_1site │ ├── DMRG_1ES_1site_Ex.m │ ├── DMRG_ExcitedState_1site.m │ ├── DMRG_ExcitedState_1site.mlx │ └── DMRG_ExcitedState_1site.pdf ├── T09.1_DMRG_ExcitedState_1site_sol │ ├── DMRG_ExcitedState_1site_sol.m │ ├── DMRG_ExcitedState_1site_sol.mlx │ └── DMRG_ExcitedState_1site_sol.pdf ├── T09.2_DMRG_GroundState_2site │ ├── DMRG_GS_2site_Ex.m │ ├── DMRG_GroundState_2site.m │ ├── DMRG_GroundState_2site.mlx │ └── DMRG_GroundState_2site.pdf ├── T09.2_DMRG_GroundState_2site_sol │ ├── DMRG_GroundState_2site_sol.m │ ├── DMRG_GroundState_2site_sol.mlx │ └── DMRG_GroundState_2site_sol.pdf ├── T10.1_iTEBD_GroundState │ ├── iTEBD_GS_Vidal_Ex.m │ ├── iTEBD_GroundState.m │ ├── iTEBD_GroundState.mlx │ └── iTEBD_GroundState.pdf ├── T10.1_iTEBD_GroundState_sol │ ├── iTEBD_GroundState_sol.m │ ├── iTEBD_GroundState_sol.mlx │ └── iTEBD_GroundState_sol.pdf ├── T11.1_iTEBD_Hastings_Ortho │ ├── iTEBD_GS_Hastings_Ex.m │ ├── iTEBD_Hastings_Ortho.m │ ├── iTEBD_Hastings_Ortho.mlx │ ├── iTEBD_Hastings_Ortho.pdf │ └── ortho_Orus_Ex.m ├── T11.1_iTEBD_Hastings_Ortho_sol │ ├── iTEBD_Hastings_Ortho_sol.m │ ├── iTEBD_Hastings_Ortho_sol.mlx │ └── iTEBD_Hastings_Ortho_sol.pdf ├── T12.1_tDMRG_ErrorAnalysis │ ├── tDMRG_ErrorAnalysis.m │ ├── tDMRG_ErrorAnalysis.mlx │ ├── tDMRG_ErrorAnalysis.pdf │ └── tDMRG_Ex.m ├── T12.1_tDMRG_ErrorAnalysis_sol │ ├── tDMRG_ErrorAnalysis_sol.m │ ├── tDMRG_ErrorAnalysis_sol.mlx │ └── tDMRG_ErrorAnalysis_sol.pdf ├── T12.2_MPO_TimeEvolution │ ├── MPO_TimeEvolution.m │ ├── MPO_TimeEvolution.mlx │ └── MPO_TimeEvolution.pdf ├── T12.2_MPO_TimeEvolution_sol │ ├── MPO_TimeEvolution_sol.m │ ├── MPO_TimeEvolution_sol.mlx │ └── MPO_TimeEvolution_sol.pdf ├── T13.1_FiniteT │ ├── FiniteT.m │ ├── FiniteT.mlx │ ├── FiniteT.pdf │ ├── XTRG_Ex.m │ ├── finT_puri_Ex.m │ └── mtimes_MPO_Ex.m ├── T13.1_FiniteT_sol │ ├── FiniteT_sol.m │ ├── FiniteT_sol.mlx │ └── FiniteT_sol.pdf ├── T14.1_NRG_Eflow │ ├── NRG_Eflow.m │ ├── NRG_Eflow.mlx │ ├── NRG_Eflow.pdf │ ├── NRG_IterDiag_Ex.m │ └── doCLD_Ex.m ├── T14.1_NRG_Eflow_sol │ ├── NRG_Eflow_sol.m │ ├── NRG_Eflow_sol.mlx │ └── NRG_Eflow_sol.pdf ├── T14.2_NRG_ImpThermodyn │ ├── NRG_ImpThermodyn.m │ ├── NRG_ImpThermodyn.mlx │ ├── NRG_ImpThermodyn.pdf │ └── getTDconv_Ex.m ├── T14.2_NRG_ImpThermodyn_sol │ ├── NRG_ImpThermodyn_sol.m │ ├── NRG_ImpThermodyn_sol.mlx │ └── NRG_ImpThermodyn_sol.pdf ├── T15.1_NRG_FullDensityMatrix │ ├── NRG_FullDensityMatrix.m │ ├── NRG_FullDensityMatrix.mlx │ ├── NRG_FullDensityMatrix.pdf │ └── getRhoFDM_Ex.m ├── T15.1_NRG_FullDensityMatrix_sol │ ├── NRG_FullDensityMatrix_sol.m │ ├── NRG_FullDensityMatrix_sol.mlx │ └── NRG_FullDensityMatrix_sol.pdf ├── T16.1_NRG_SpectralFunc │ ├── NRG_SpectralFunc.m │ ├── NRG_SpectralFunc.mlx │ ├── NRG_SpectralFunc.pdf │ └── getAdisc_Ex.m ├── T16.1_NRG_SpectralFunc_sol │ ├── NRG_SpectralFunc_sol.m │ ├── NRG_SpectralFunc_sol.mlx │ └── NRG_SpectralFunc_sol.pdf ├── T16.2_Lehmann_NonInt │ ├── Lehmann_NonInt.pdf │ └── Lehmann_NonInt.tex ├── T16.2_Lehmann_NonInt_sol │ ├── Lehmann_NonInt_sol.pdf │ └── Lehmann_NonInt_sol.tex ├── T17.1_NRG_SelfEnergy │ ├── KKi2r_Ex.m │ ├── NRG_SelfEnergy.m │ ├── NRG_SelfEnergy.mlx │ ├── NRG_SelfEnergy.pdf │ └── SEtrick_Ex.m ├── T17.1_NRG_SelfEnergy_sol │ ├── NRG_SelfEnergy_sol.m │ ├── NRG_SelfEnergy_sol.mlx │ └── NRG_SelfEnergy_sol.pdf ├── T17.2_DMFT_NRG │ ├── DMFT_Hubbard_Ex.m │ ├── DMFT_NRG.m │ ├── DMFT_NRG.mlx │ └── DMFT_NRG.pdf ├── T17.2_DMFT_NRG_sol │ ├── DMFT_NRG_sol.m │ ├── DMFT_NRG_sol.mlx │ └── DMFT_NRG_sol.pdf ├── T18.1_TDVP_1site_ErrorAnalysis │ ├── TDVP_1site_ErrorAnalysis.m │ ├── TDVP_1site_ErrorAnalysis.mlx │ ├── TDVP_1site_ErrorAnalysis.pdf │ └── TDVP_1site_Ex.m ├── T18.1_TDVP_1site_ErrorAnalysis_sol │ ├── TDVP_1site_ErrorAnalysis_sol.m │ ├── TDVP_1site_ErrorAnalysis_sol.mlx │ └── TDVP_1site_ErrorAnalysis_sol.pdf ├── T19.1_TDVP_2site_ErrorAnalysis │ ├── TDVP_2site_ErrorAnalysis.m │ ├── TDVP_2site_ErrorAnalysis.mlx │ ├── TDVP_2site_ErrorAnalysis.pdf │ └── TDVP_2site_Ex.m ├── T19.1_TDVP_2site_ErrorAnalysis_sol │ ├── TDVP_2site_ErrorAnalysis_sol.m │ ├── TDVP_2site_ErrorAnalysis_sol.mlx │ └── TDVP_2site_ErrorAnalysis_sol.pdf ├── T19.2_EnergyVariance │ ├── EnergyVariance.m │ ├── EnergyVariance.mlx │ ├── EnergyVariance.pdf │ └── varE_2site_Ex.m ├── T19.2_EnergyVariance_sol │ ├── EnergyVariance_sol.m │ ├── EnergyVariance_sol.mlx │ └── EnergyVariance_sol.pdf ├── T20.1_CBE_DMRG │ ├── CBE_DMRG.m │ ├── CBE_DMRG.mlx │ ├── CBE_DMRG.pdf │ └── DMRG_GS_CBE_Ex.m ├── T20.1_CBE_DMRG_sol │ ├── CBE_DMRG_sol.m │ ├── CBE_DMRG_sol.mlx │ └── CBE_DMRG_sol.pdf ├── T21.1_finite_PEPS │ ├── contract_finPEPS_Ex.m │ ├── finite_PEPS.m │ ├── finite_PEPS.mlx │ └── finite_PEPS.pdf ├── T21.1_finite_PEPS_sol │ ├── finite_PEPS_sol.m │ ├── finite_PEPS_sol.mlx │ └── finite_PEPS_sol.pdf ├── T22.1_iPEPS_CTMRG │ ├── iPEPS_CTMRG.m │ ├── iPEPS_CTMRG.mlx │ ├── iPEPS_CTMRG.pdf │ └── symCTMRG_Ex.m ├── T22.1_iPEPS_CTMRG_sol │ ├── iPEPS_CTMRG_sol.m │ ├── iPEPS_CTMRG_sol.mlx │ └── iPEPS_CTMRG_sol.pdf ├── T23.1_SimpleUpdate_TRG │ ├── SimpleUp_Honeycomb_Ex.m │ ├── SimpleUpdate_TRG.m │ ├── SimpleUpdate_TRG.mlx │ ├── SimpleUpdate_TRG.pdf │ └── TRG_Honeycomb_Ex.m ├── T23.1_SimpleUpdate_TRG_sol │ ├── SimpleUpdate_TRG_sol.m │ ├── SimpleUpdate_TRG_sol.mlx │ └── SimpleUpdate_TRG_sol.pdf ├── T24.1_GILT │ ├── GILT.m │ ├── GILT.mlx │ ├── GILT.pdf │ └── TRG_GILT_Square_Ex.m ├── T24.1_GILT_sol │ ├── GILT_sol.m │ ├── GILT_sol.mlx │ └── GILT_sol.pdf ├── T25.1_MachineLearning │ ├── ML_MPS_Ex.m │ ├── MNIST_test.csv │ ├── MNIST_train.csv.zip │ ├── MachineLearning.m │ ├── MachineLearning.mlx │ └── MachineLearning.pdf └── T25.1_MachineLearning_sol │ ├── MachineLearning_sol.m │ ├── MachineLearning_sol.mlx │ └── MachineLearning_sol.pdf ├── Util ├── KKi2r.m ├── byte2read.m ├── chkmem.m ├── disptime.m ├── nonIntTB.m ├── tic2.m └── toc2.m ├── readme.mlx ├── readme.pdf └── startup.m /DMRG/XTRG.m: -------------------------------------------------------------------------------- 1 | function [taus,lnZs,rho] = XTRG (Hs,dt,tmax,Nkeep,Nsweep) 2 | % < Description > 3 | % 4 | % [taus,lnZs,rho] = XTRG (Hs,dt,tmax,Nkeep,Nsweep) 5 | % 6 | % Exponential tensor renormalization group (XTRG) method for simulating 7 | % thermal density matrix as a matrix product operator (MPO). This function 8 | % takes logarithmic imaginary-time steps and evaluates the logarithm of the 9 | % partition function at those time instances. 10 | % 11 | % < Input > 12 | % Hs : [1 x N cell array] MPO representation of the Hamiltonian. Each Hs{n} 13 | % is a rank-4 tensor acting on site n. The order of legs of Hs{n} is 14 | % bottom-top-left-right, where the bottom (top) leg contracts to the 15 | % physical leg of bra (ket) tensor. 16 | % dt : [numeric] Initial value of the imaginary time. In this function, the 17 | % first thermal density matrix in its MPO form is constructied via 18 | % linearization, i.e., I - dt*H, where I is the identity for the 19 | % whole Hilbert space and H is the Hamiltonian. 20 | % tmax : [numeric] Maximum time to be reached at the end of iterations. 21 | % "tmax" equals to the target inverse temperature. 22 | % Nkeep : [integer] Maximum bond dimension of the MPO form of the purified 23 | % thermal state. 24 | % Nsweep : [integer] Number of round trips in the variational MPO 25 | % multiplication. "Nkeep" and "Nsweep" are directly forwarded to 26 | % "DMRG/mtimes_MPO.m"; see the description of those inputs therein. 27 | % 28 | % < Output > 29 | % taus : [numeric] Time instances taken by logarithmically within the XTRG. 30 | % The actual imaginary time instances are -1i*taus. The elements of 31 | % "taus" equal to the inverse temperature values. 32 | % lnZs : [numeric] Logarithms of the partition function measured at time 33 | % instances "taus". 34 | % rho : [cell] The MPO representation of the thermal density matrix at the 35 | % last time instance. 36 | % 37 | % Written by S.Lee (Oct.10,2022) 38 | 39 | tobj = tic2; 40 | 41 | N = numel(Hs); 42 | 43 | % % % % TODO (start) % % % % 44 | % initialize the first thermal density matrix, given by linearizing the 45 | % exponential, I - dt*H, where H is the MPO Hamiltonian 46 | rho = cell(1,N); 47 | rho{1} = cat(4,getIdentity(Hs{1},2),-dt*Hs{1}); 48 | for itN = (2:N-1) 49 | sz = [size(Hs{itN}),ones(1,4-ndims(Hs{itN}))]; 50 | rho{itN} = cat(3, ... 51 | cat(4,getIdentity(Hs{itN},2),zeros([sz(1:2) 1 sz(4)])), ... 52 | cat(4,zeros([sz(1:2) sz(3)]),Hs{itN})); 53 | end 54 | rho{N} = cat(3,getIdentity(Hs{1},2),Hs{N}); 55 | % % % % TODO (end) % % % % 56 | 57 | Nstep = round(log2(tmax)-log2(dt)); 58 | taus = dt*(2.^(1:Nstep)); 59 | lnZs = zeros(size(taus)); % result 60 | 61 | % show information 62 | fprintf('Finite T: XTRG\n'); 63 | fprintf(['N = ',sprintf('%i',N),', Nkeep = ',sprintf('%i',Nkeep), ... 64 | ', Nsweep = ',sprintf('%i',Nsweep), ... 65 | ', dt = ',sprintf('%.4g',dt),', tmax = ',sprintf('%.4g',taus(end)), ... 66 | ' (',sprintf('%.4g',Nstep),' steps)\n']); 67 | 68 | % main part of XTRG; iterative "squaring" of density matrix 69 | for it1 = (1:Nstep) 70 | % Hermitian conjugate 71 | rho2 = rho; 72 | for itN = (1:N) 73 | rho2{itN} = permute(conj(rho2{itN}),[2 1 3 4]); 74 | end 75 | 76 | % MPO multiplication 77 | rho = mtimes_MPO(rho2,rho,Nkeep,Nsweep); 78 | 79 | % % % % TODO (start) % % % % 80 | % compute the trace, which leads to the partition function 81 | Tr = 1; 82 | for itN = (1:N) 83 | Tr = contract(Tr,2,2,rho{itN},4,3); 84 | Tr = contract(Tr,4,[2 3],getIdentity(Tr,3),2,[2 1]); 85 | end 86 | 87 | % add the log of the trace to the result array lnZs 88 | lnZs(it1) = log(Tr); 89 | 90 | % add the result from the last iteration, since the MPO gets normalized 91 | % at every iteration (see below) to avoid divergence 92 | if it1 > 1 93 | lnZs(it1) = lnZs(it1) + 2*lnZs(it1-1); 94 | end 95 | 96 | % normalize the MPO 97 | rho{1} = rho{1}/Tr; 98 | % % % % TODO (end) % % % % 99 | 100 | if (mod(it1,round(Nstep/10)) == 0) || (it1 == Nstep) 101 | disptime(['#',sprintf('%i/%i',[it1,Nstep]), ... 102 | ' : t = ',sprintf('%.4g/%.4g',[taus(it1),taus(end)])]); 103 | end 104 | end 105 | 106 | toc2(tobj,'-v'); 107 | chkmem; 108 | 109 | end 110 | -------------------------------------------------------------------------------- /NRG/DMFT_Hubbard.m: -------------------------------------------------------------------------------- 1 | function [ocont,RhoV2s,iscvg] = DMFT_Hubbard (U,mu,T,D,ozin,RhoV2in,Lambda,N,Nkeep) 2 | % < Description > 3 | % 4 | % [ocont,RhoV2s] = DMFT_Hubbard (U,mu,T,D,ozin,RhoV2in,Lambda,N,Nkeep) 5 | % 6 | % Perform the DMFT calculation of the one-band Hubbard model with the NRG 7 | % as an impurity solver. Here we consider a lattice (on which the Hubbard 8 | % model is defined) whose non-interacting density of states is semi-ellipse 9 | % of half-bandwidth D. Such density of states is known to come from the 10 | % Bethe lattice with infinite coordination number. 11 | % 12 | % < Input > 13 | % U, mu, T, D : [numeric] Parameters that define the Hubbard model. 14 | % Interaction strength, chemical potential, temperature, and the 15 | % half-bandwidth of the non-interacting density of states, 16 | % respectively. 17 | % ozin, RhoV2in : [vector] Initial hybridization function to start the 18 | % DMFT self-consistency loop. The function is assumed to be the 19 | % linear interpolation among the data points (ozin vs. RhoV2in), and 20 | % it is re-evaluted on the frequency grid "ocont" (see below); then 21 | % the re-evaluated data is fed into the logarithmic discretization 22 | % routine ("doCLD"). 23 | % Lambda, N, Nkeep : [numeric] NRG parameters. Logarithmic discretization 24 | % parameter, the maximum of the Wilson chain length, and the maximum 25 | % number of kept states, respectively. "Lambda" and "N" are directly 26 | % fed into "doCLD" and "Nkeep" into "NRG_IterDiag". 27 | % 28 | % < Output > 29 | % ocont : [vector] Frequency grid on which the hybridization functions 30 | % ("RhoV2s"; see below) are defined. Here we use the default output 31 | % of "getAcont". 32 | % RhoV2s : [matrix] Hybridization functions that are updated during the 33 | % DMFT self-consistency loop. At the n-th iteration of the loop (n = 34 | % 1, 2, 3, ...), RhoV2s(:,n) is used as the input (fed into "doCLD"). 35 | % The new hybridization function, as the result of the iteration by 36 | % using "getAdisc", "getAcont", "SEtrick", etc., is stored as 37 | % RhoV2s(:,n+1), which is directly used as the input for the next 38 | % iteration. The size of "RhoV2s" is numel(ocont)-by-(m+1), where m 39 | % is the number of DMFT iterations taken. 40 | % iscvg : [logical] If true, the DMFT self-consistency is achieved up to 41 | % a tolerance (set by "cvgth"; see inside the code). If false, the 42 | % self-consistency loop is terminated since it reached the maximnum 43 | % iteration index (set by "Ndmft"; see inside the code). 44 | % 45 | % Rewritten by S.Lee (Oct.28,2022): Revised for the TN lecture course at 46 | % SNU. 47 | 48 | % % default values of parameters 49 | Ndmft = 30; % maximum number of DMFT iterations 50 | 51 | % DMFT convergence criterion. If the difference between the old 52 | % hybridization function (the input to "doZLD") and the new hybridization 53 | % function (the output from a DMFT iteration) is smaller than "cvgth" for 54 | % all frequencies, the DMFT self-consistency is achieved. 55 | cvgth = 1e-3; 56 | % % % % % 57 | 58 | % % % % TODO (start) % % % % 59 | 60 | % Construct local operators 61 | [F,Z,~,I] = getLocalSpace('FermionS'); 62 | 63 | % Particle number operators 64 | NF = cat(3,contract(conj(F(:,:,1)),3,[1 3],F(:,:,1),3,[1 3]), ... 65 | contract(conj(F(:,:,2)),3,[1 3],F(:,:,2),3,[1 3])); 66 | 67 | % Impurity Hamiltonian 68 | HU = U*(NF(:,:,1)*NF(:,:,2)); 69 | H0 = HU + (-mu)*(NF(:,:,1)+NF(:,:,2)); 70 | 71 | % commutator [F, HU] to define the auxiliary correlator 72 | FHU = contract(F,3,2,HU,2,1,[1 3 2]) - contract(HU,2,2,F,3,1); 73 | 74 | % ket tensor for the impurity 75 | A0 = getIdentity(1,2,I,2,[1 3 2]); % 1 for dummy leg 76 | 77 | % this step does not change the data of H0, but it is concenptually 78 | % needed; H0 is defined in the space spanned by the 2nd leg of A0 79 | H0 = updateLeft([],[],A0,H0,2,A0); 80 | 81 | ocont = getAcont(0,0,0,0); 82 | RhoV2s = zeros(numel(ocont),Ndmft+1); 83 | oks = (ocont <= max(ozin)) & (ocont >= min(ozin)); 84 | RhoV2s(oks,1) = interp1(ozin,RhoV2in,ocont(oks),'linear'); 85 | iscvg = false; 86 | 87 | for itd = (1:Ndmft) 88 | [ff,gg] = doCLD(ocont,RhoV2s(:,itd),Lambda,N); 89 | 90 | % iterative diagonalization 91 | Inrg = NRG_IterDiag(H0,A0,Lambda,ff,F,gg,sum(NF,3),Z,Nkeep); 92 | 93 | Inrg = getRhoFDM(Inrg,T); 94 | 95 | [odisc,Adisc1] = getAdisc(Inrg,F(:,:,1),F(:,:,1),Z); 96 | [~ ,Adisc2] = getAdisc(Inrg,FHU(:,:,1),F(:,:,1),Z); 97 | 98 | [ocont,Acont1] = getAcont(odisc,Adisc1,log(Lambda),T/5); 99 | [~ ,Acont2] = getAcont(odisc,Adisc2,log(Lambda),T/5); 100 | 101 | SE = SEtrick(ocont,Acont1,Acont2); 102 | 103 | xi = ocont + mu - SE; 104 | Glat = (2/(D^2))*(xi - 1i*sqrt(D^2 - xi.^2)); 105 | Alat = (-1/pi)*imag(Glat); 106 | RhoV2s(:,itd+1) = ((D/2)^2)*Alat; 107 | 108 | if max(abs(RhoV2s(:,itd+1)-RhoV2s(:,itd)),[],1) < cvgth 109 | disptime('DMFT converged; exit the loop.'); 110 | iscvg = true; 111 | break; 112 | end 113 | end 114 | 115 | RhoV2s(:,itd+2:end) = []; 116 | 117 | % % % % TODO (end) % % % % 118 | 119 | 120 | end -------------------------------------------------------------------------------- /NRG/SEtrick.m: -------------------------------------------------------------------------------- 1 | function [SE,varargout] = SEtrick (ocont,Acont1,Acont2,varargin) 2 | % < Description > 3 | % 4 | % SE = SEtrick (ocont,Acont1,Acont2) % self-energy only 5 | % [SE,Aimp] = SEtrick (ocont,Acont1,Acont2,epsd,RhoV2in) % also obtain 6 | % % the improved estimate of the impurity spectral function 7 | % 8 | % Compute the impurity self-energy due to interactions and (if "epsd" and 9 | % "RhoV2in" are given) the improved estimate of the impurity spectral 10 | % function by using Bulla's "self-energy trick", developed in [R. Bulla, A. 11 | % C. Hewson, and Th. Pruschke, J. Phys. Condens. Matter 10, 8365 (1998)]. 12 | % Based on the equation of motion (EoM) for the impurity Green's function 13 | % G[F, F'] that is derived by differentiating the function with respect to 14 | % the first time argument for the first operator F, the self-energy SE can 15 | % be given by the ratio of two correlation functions, 16 | % SE = G[FH, F'] / G[F, F'], ----- (1) 17 | % where F is the particle annihilation operator at the impurity, F' is the 18 | % Hermitian conjugate of F, FH = [F, HU] is the commutator, and HU means 19 | % the interaction (i.e., non-quadratic) term of the impurity Hamiltonian. 20 | % 21 | % < Input > 22 | % ocont : [numeric vector] Frequency grid on which "Acont1" and "Acont2" 23 | % (also "RhoV2in", if given) are defined. 24 | % Acont1 : [numeric] The spectral function part of a correlator G[F, F']. 25 | % This 'Acont1' is the broadned curve (by using 'getAcont') from the 26 | % discrete spectral data of the spectral function of G[F,F'] (by 27 | % running 'getAdisc'). 28 | % Acont2 : [numeric] The spectral function part of a correlator G[FH, F']. 29 | % It is obtained in a similar way as "Acont1", while using FH instead 30 | % of F. 31 | % epsd : (Optional) [numeric] Impurity level. 32 | % RhoV2in : (Optional) [numeric] The spectral function part of the 33 | % hybridization function defined on the frequency grid "ocont". 34 | % 35 | % < Output > 36 | % The data structure (in terms of dimensions) of the following results are 37 | % the same as the input Acont1. 38 | % SE : [numeric] Impurity self-energy. 39 | % Aimp : (Optional) [numeric] Improved impurity spectral function, obtained 40 | % by susbstituting the self-energy "SE" and the optional input 41 | % "RhoV2in" into the Dyson equation. 42 | % 43 | % Written by S.Lee (Oct.28,2022): for the TN lecture course at SNU. 44 | 45 | % default values of numerical parameter and optional inputs 46 | iSEmax = -1e-14; % maximum of the imaginary part of the self-energy, needed 47 | % to post-process the self-energy; see below 48 | epsd = []; 49 | RhoV2in = []; 50 | 51 | % parse optional input 52 | if ~isempty(varargin) 53 | if numel(varargin) < 2 54 | error('ERR: If optional inputs are given, there should be two optional inputs.'); 55 | end 56 | epsd = varargin{1}; 57 | RhoV2in = varargin{2}; 58 | end 59 | 60 | % sanity check 61 | if ~isvector(ocont) 62 | error('ERR: ''ocont'' should be a vector.'); 63 | elseif ~ismatrix(Acont1) || ~ismatrix(Acont2) 64 | error('ERR: ''Acont1'' and ''Acont2'' should be matrices.'); 65 | elseif ~all(numel(ocont) == [size(Acont1,1) size(Acont2,1)]) 66 | error('ERR: size(Acont1,1) and size(Acont2,1) should be equal to numel(ocont).'); 67 | elseif size(Acont1,2) ~= size(Acont2,2) 68 | error('ERR: size(Acont1,2) and size(Acont2,2) should be the same.'); 69 | elseif isempty(RhoV2in) ~= isempty(epsd) 70 | error('ERR: Only one optional input was set?'); 71 | elseif ~isempty(RhoV2in) 72 | if ~ismatrix(RhoV2in) 73 | error('ERR: RhoV2in should be a matrix.'); 74 | elseif numel(ocont) ~= size(RhoV2in,1) 75 | error('ERR: size(RhoV2in,1) should be equal to numel(ocont).'); 76 | elseif size(epsd,1) ~= 1 77 | error('ERR: ''epsd'' should be a row vector.'); 78 | elseif ~all(size(Acont1,2) == [size(epsd,2) size(RhoV2in,2)]) 79 | error('ERR: size(epsd,2) and size(RhoV2in,2) should be equal to size(Acont1,2).'); 80 | end 81 | end 82 | % % % % 83 | 84 | % % % % TODO (start) % % % % 85 | 86 | % complete correlators 87 | G1 = (-pi)*(KKi2r(ocont,Acont1)+1i*Acont1); 88 | G2 = (-pi)*(KKi2r(ocont,Acont2)+1i*Acont2); 89 | SE = G2./G1; % self-energy 90 | 91 | % The imaginary part of the self-energy should be negative, to ensure the 92 | % causality. However, in this numerical calculation, the imaginary part can 93 | % be slightly positive over a narrow interval. To make the numerical result 94 | % of SE physically sound, we cut off the imaginary part larger than 95 | % "iSEmax" (defined above) to be bounded by "iSEmax". 96 | oks = (imag(SE) > iSEmax); 97 | SE(oks) = real(SE(oks)) + 1i*iSEmax; 98 | 99 | if ~isempty(RhoV2in) % compute the improved estimate of the impurity spectral function 100 | % complete hybridization function, having both real and imaginary parts 101 | Deltaw = (-pi)*(KKi2r(ocont,RhoV2in)+1i*RhoV2in); 102 | Gimp = 1./(ocont - epsd - Deltaw - SE); 103 | varargout = {(-1/pi)*imag(Gimp)}; 104 | end 105 | 106 | % % % % TODO (end) % % % % 107 | 108 | end -------------------------------------------------------------------------------- /NRG/getRhoFDM.m: -------------------------------------------------------------------------------- 1 | function Inrg = getRhoFDM (Inrg,T) 2 | % < Description > 3 | % 4 | % Inrg = getRhoFDM_Ex (Inrg,T) 5 | % 6 | % Construct the full density matrix (FDM) in the basis of both discarded 7 | % and kept states, for given temperature T. 8 | % 9 | % < Input > 10 | % Inrg : [struct] NRG information obtained after running NRG_IterDiag. 11 | % T : [number] Temperature. Here we set \hbar = k_B = 1. 12 | % 13 | % < Ouput > 14 | % Inrg : [struct] NRG result. It keeps the result of NRG_IterDiag. In 15 | % addition to the result, this function adds two more fields to Inrg: 16 | % .RD, .RK : [cell] Full density matrix in the discarded and kept state 17 | % basis, respectively. Each cell element Inrg.RD{n} is a column 18 | % vector whose elements are the density matrix elements associated 19 | % with the discarded energy eigenstates at iteration n-1. (Refer to 20 | % the documentation of NRG_IterDiag for the interation indexing 21 | % convention.) 22 | % Inrg.RK{n} is a matrix in the basis of the kept energy eigenstates 23 | % at the iteration n-1. 24 | % 25 | % Written by S.Lee (May 22,2017) 26 | % Updated by S.Lee (May 12,2019): Revised for SoSe 2019. 27 | % Updated by S.Lee (Jun.20,2020): Revised for SoSe 2020. 28 | % Updated by S.Lee (Oct.22,2020): Revised for the 2022 Fall semester at SNU. 29 | 30 | tobj = tic2; 31 | disptime(['Construct full density matrix @ T = ',sprintf('%.4g',T),'.']); 32 | 33 | N = numel(Inrg.E0); 34 | 35 | % extract the local space dimension from ket tensors 36 | locdim = zeros(N,1); 37 | for itN = (1:N) 38 | if ~isempty(Inrg.AK{itN}) 39 | locdim(itN) = size(Inrg.AK{itN},3); 40 | else 41 | locdim(itN) = size(Inrg.AD{itN},3); 42 | end 43 | end 44 | 45 | RD = cell(1,N); % FDM in the discarded state basis; row vector 46 | RK = cell(1,N); % FDM in the kept state basis; matrix 47 | Ztot = zeros(1,N); % sum of Boltzmann weights 48 | 49 | % % % % TODO (start) % % % % 50 | % the shift of energy in each shell measured from the lowest-energy of the 51 | % last iteration 52 | E0r = [Inrg.EScale(2:end).*Inrg.E0(2:end),0]; 53 | E0r = fliplr(cumsum(fliplr(E0r))); 54 | 55 | % obtain the Boltzamann weights 56 | for itN = (1:N) 57 | % Obtain the column vector RD{itN} whose elements are the Boltzmann 58 | % weights 59 | RD{itN} = exp(-(Inrg.ED{itN}*Inrg.EScale(itN)-E0r(itN))/T)*prod(locdim(itN+1:end)); 60 | Ztot(itN) = sum(RD{itN}); 61 | end 62 | 63 | Ztot = sum(Ztot); 64 | 65 | % normalize the Boltzmann weights to get the elements of the density matrix 66 | % in the discarded basis 67 | for itN = (1:N) 68 | RD{itN} = RD{itN}/Ztot; 69 | end 70 | 71 | % update the FDM in the kept basis 72 | for itN = (N:-1:2) 73 | % Construct RK{itN-1} as the sum of RD{itN} and RK{itN}, with the local 74 | % Hilbert space for the site s(itN-1). 75 | AD2 = permute(conj(Inrg.AD{itN}),[2 1 3]); 76 | AK2 = permute(conj(Inrg.AK{itN}),[2 1 3]); 77 | RK{itN-1} = updateLeft(diag(RD{itN}),2,AD2,[],[],AD2) ... 78 | + updateLeft(RK{itN},2,AK2,[],[],AK2); 79 | % NOTE: AK and AD are in left-canonical form, not right-canonical. 80 | 81 | end 82 | % % % % TODO (end) % % % % 83 | 84 | if sum(RD{end}) > 1e-2 85 | disptime('WRN: sum(Inrg.RD{end}) > 1e-2 ; chain length may not be long enough.'); 86 | end 87 | 88 | Inrg.T = T; % record T in Inrg 89 | Inrg.Ztot = Ztot; % record the sum of Boltzmann weights 90 | Inrg.RK = RK; 91 | Inrg.RD = RD; 92 | 93 | toc2(tobj,'-v'); 94 | 95 | end -------------------------------------------------------------------------------- /PEPS/contPlaq.m: -------------------------------------------------------------------------------- 1 | function T = contPlaq (varargin) 2 | % < Description > 3 | % 4 | % T = contPlaq (A,B,C,D, ...) 5 | % 6 | % Contract rank-3 tensors A, B, C, ... placed around a plaquette. The 7 | % tensors are placed around the plaquette in counter-clockwise order, and 8 | % the legs of individual tensor are ordered in counter-clockwise order. For 9 | % example, if there are 4 input tensors A, B, C, and D, the output T is 10 | % 11 | % \2 2/ 12 | % \ 1 3 / 13 | % A ------ D 1\ /4 14 | % 3| |1 \ / 15 | % | | ==> T 16 | % 1| |3 / \ 17 | % B ------ C 2/ \3 18 | % / 3 1 \ 19 | % /2 2\ 20 | % 21 | % < Input > 22 | % A, B, .. : [tensors] Tensors aroung a plaquette. The order of tensors A, 23 | % B, .. is (counter-)clockwise and the order of the legs of each 24 | % tensor is also (counter-)clockwise. 25 | % 26 | % < Output > 27 | % T : [tensor] Contraction result. The legs follows the same order of 28 | % input. 29 | % 30 | % Written by S.Lee (Jul.12,2017) 31 | % Updated by S.Lee (Jul.08,2019): Documentation updated 32 | 33 | n = nargin; % number of tensors 34 | T = varargin{1}; 35 | 36 | for it = (2:n-1) 37 | T = contract(T,it+1,it+1,varargin{it},3,1); 38 | end 39 | 40 | T = contract(T,n+1,[1 n+1],varargin{n},3,[3 1]); 41 | 42 | end -------------------------------------------------------------------------------- /PEPS/contract_finPEPS.m: -------------------------------------------------------------------------------- 1 | function res = contract_finPEPS (T,Nkeep,Nsweep) 2 | % < Description > 3 | % 4 | % res = contract_finPEPS (T,Nkeep,Nsweep) 5 | % 6 | % Contract the reduced tensors on a finite square lattice with open 7 | % boundary conditions, by using the MPO-MPS method. That is, the first row 8 | % of the tensor array is regarded as an MPS (with fat bonds and physical 9 | % legs), and the second, third, etc. rows are absorbed into the firt row 10 | % sequentially, by using the variational multiplication implemented in 11 | % DMRG/mtimes_MPO.m. Note that in "mtimes_MPO" an MPO is multiplied with 12 | % the other MPO, not MPS. But here an MPO whose up legs have all singleton 13 | % dimentions can be regarded as an MPS, so we can use the function. 14 | % 15 | % < Input > 16 | % T : [cell array] T{m,n} is a rank-4 reduced tensor, obtained by 17 | % contracting a rank-5 tensor at site (m,n) from the projected 18 | % entangled-pair state (PEPS) as a ket state and the tensor's complex 19 | % conjugate. If an expectation value of a local operator or a product 20 | % of local operators is to be measured, then those local operators 21 | % are sandwiched between the physical legs of the rank-5 tensor and 22 | % its conjugate. 23 | % The legs of each T{m,n} are ordered as left-up-down-right. 24 | % Nkeep : [numeric] The maximum bond dimension along the horizontal 25 | % direction. 26 | % Nsweep : [numeric] Number of sweeps to be performed in each of MPO-MPS 27 | % multiplication. This parameter is handed over to "mtimes_MPO" used 28 | % as a sub-function here. 29 | % 30 | % < Output > 31 | % res : [numeric] Contraction result. 32 | % 33 | % Written by S.Lee (Nov.13,2022): for the lecture course at SNU. 34 | 35 | tobj = tic2; 36 | 37 | % sanity check 38 | for it1 = (1:size(T,1)) 39 | for it2 = (1:size(T,2)) 40 | if (it1 < size(T,1)) && (size(T{it1,it2},3) ~= size(T{it1+1,it2},2)) 41 | error(['ERR: The down leg of T{',sprintf('%i,%i',it1,it2), ... 42 | '} and the up leg of T{',sprintf('%i,%i',it1+1,it2),'} do not match.']) 43 | elseif (it2 < size(T,2)) && (size(T{it1,it2},4) ~= size(T{it1,it2+1},1)) 44 | error(['ERR: The right leg of T{',sprintf('%i,%i',it1,it2), ... 45 | '} and the left leg of T{',sprintf('%i,%i',it1,it2+1),'} do not match.']) 46 | elseif (it1 == 1) && (size(T{it1,it2},2) ~= 1) 47 | error(['ERR: The up leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 48 | elseif (it1 == size(T,1)) && (size(T{it1,it2},3) ~= 1) 49 | error(['ERR: The down leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 50 | elseif (it2 == 1) && (size(T{it1,it2},1) ~= 1) 51 | error(['ERR: The left leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 52 | elseif (it2 == size(T,2)) && (size(T{it1,it2},4) ~= 1) 53 | error(['ERR: The right leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 54 | end 55 | end 56 | end 57 | % % % 58 | 59 | disptime(['Contract tensors on a ',sprintf('%i x %i',[size(T,1) size(T,2)]), ... 60 | ' lattice, with Nkeep = ',sprintf('%i',Nkeep)]); 61 | 62 | % % permute legs of T{..}, to use DMRG/mtimes_MPO 63 | for itN = (1:numel(T)) 64 | T{itN} = permute(T{itN},[3 2 1 4]); % down-up-left-right 65 | end 66 | 67 | % reduced tensors are not strictly normalized, so their contraction can 68 | % lead to very small or large numbers. In such cases, numerical procedures 69 | % can be unstable; sometimes one gets just 0 or Inf. To avoid this, 70 | % separate the norm of the contracted MPO after each step, and collect the 71 | % norms as the sum of their logarithms. 72 | logNorm = 0; 73 | 74 | % first row of reduced tensors as an MPO 75 | T2 = T(1,:); 76 | 77 | % % % % TODO (start) % % % % 78 | for it1 = (2:size(T,1)-1) 79 | T2 = mtimes_MPO (T(it1,:),T2,Nkeep,Nsweep); 80 | 81 | % factor out the norm by bringing into a right-canonical form 82 | % First, convert rank-4 tensors into rank-3, by merging physical legs, to 83 | % use the canonForm function that canonicalize MPSs 84 | Aloc = cell(1,size(T,2)); % isometries for merging the bottom and top legs of MPO tensors 85 | for it2 = (1:size(T,2)) 86 | Aloc{it2} = getIdentity(T2{it2},1,T2{it2},2); 87 | T2{it2} = contract(T2{it2},4,[1 2],Aloc{it2},3,[1 2]); 88 | end 89 | % Use canonForm for MPS 90 | [T2,S] = canonForm(T2,0,Nkeep,[]); 91 | % Bring back to rank-4 92 | for it2 = (1:size(T,2)) 93 | T2{it2} = contract(T2{it2},3,3,conj(Aloc{it2}),3,3,[3 4 1 2]); 94 | end 95 | 96 | logNorm = logNorm + log(S); 97 | end 98 | 99 | % contract the contraction result of the rows so far (all but except the 100 | % last row) and the last row 101 | res = 1; 102 | for it2 = (1:size(T,2)) 103 | Ttmp = contract(res,2,2,T2{it2},4,3); 104 | res = contract(T{end,it2},4,[3 2 1],Ttmp,4,(1:3)); 105 | end 106 | % % % % TODO (end) % % % % 107 | 108 | % restore the separted norm 109 | res = res*exp(logNorm); 110 | 111 | toc2(tobj,'-v'); 112 | 113 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tensor Networks 2022 2 | 3 | Please refer to [readme.pdf](https://github.com/ssblee/TensorNetworks2022/blob/main/readme.pdf) to start with. 4 | -------------------------------------------------------------------------------- /Tensor/canonForm.m: -------------------------------------------------------------------------------- 1 | function [M,S,dw] = canonForm (M,id,Nkeep,Skeep) 2 | % < Description > 3 | % 4 | % [M,S,dw] = canonForm (M,id,Nkeep,Skeep); 5 | % 6 | % Obtain the canonical forms of MPS, depending on the index id of the 7 | % target bond. The left part of the MPS, M{1}, ..., M{id}, is brought into 8 | % the left-canonical form and the right part of the MPS; M{id+1}, ..., 9 | % M{end}, into the right-canonical form. Thus, if id is 0, the result is 10 | % purely right-canonical form; if id is numel(M), the result is purely 11 | % left-canonical form. 12 | % 13 | % < Input > 14 | % M : [cell array] MPS of length numel(M). Each cell element is a rank-3 15 | % tensor, where the first, second, and third dimensions are 16 | % associated with left, right, and bottom (i.e., physical) legs, 17 | % respectively. 18 | % id : [integer] Index for the bond connecting the tensors M{id} and 19 | % M{id+1}. With respect to the bond, the tensors to the left 20 | % (right) are brought into the left-(right-)canonical form. 21 | % Nkeep : [number] Maximal number of singular values to keep at each SVD. 22 | % If set empty ([]), it is interpreted as Inf, meaning no truncation 23 | % by the number of singular values. 24 | % Skeep : [number] Minimum magnitude of the singluar value to keep at each 25 | % SVD. If set empty ([]), it is interpreted as 10*eps(S(1)), where 26 | % S(1) means the largest singular value. Not to truncate by the 27 | % magnitude of singular values, set Skeep = 0. 28 | % 29 | % < Output > 30 | % M : [cell array] Left-, right-, or bond-canonical form from input M, 31 | % depending on id, as follows: 32 | % * id == 0: right-canonical form 33 | % * id == numel(M): left-canonical form 34 | % * otherwise: bond-canonical form 35 | % S : [column vector] Singular values at the bond between M{id} and M{id+1} 36 | % if 0 < id < numel(M); the norm of the MPS if id = 1 or numel(M). 37 | % dw : [column vector] Vector of length numel(M)-1. dw(n) means the 38 | % discarded weight (i.e., the sum of the square of the singular 39 | % values that are discarded) at the bond between M{n} and M{n+1}. 40 | % 41 | % Written by S.Lee (Apr.30,2019) 42 | % Rewritten by S.Lee (Sep.12,2022) 43 | 44 | try 45 | 46 | % % check the integrity of input 47 | if (numel(id) ~= 1) || (round(id) ~= id) 48 | error('ERR: 2nd input ''id'' needs to be a single integer.'); 49 | elseif (id < 0) || (id > numel(M)) 50 | error('ERR: the 2nd input ''id'' needs to be in a range (0:numel(M))'); 51 | elseif size(M{1},1) ~= 1 52 | error('ERR: the first dimension (= left leg) of M{1} should be of size 1.'); 53 | elseif size(M{end},2) ~= 1 54 | error('ERR: the second dimension (= right leg) of M{end} should be of size 1.'); 55 | end 56 | % % % % 57 | 58 | dw = zeros(numel(M)-1,1); % discarded weights 59 | 60 | % % Bring the left part of MPS into the left-canonical form 61 | for it = (1:id-1) 62 | % % % TODO (start) % % % 63 | 64 | % reshape M{it} and SVD 65 | [M{it},S,Vd,dw(it)] = svdTr(M{it},3,[1 3],Nkeep,Skeep); 66 | M{it} = permute(M{it},[1 3 2]); 67 | 68 | % contract S and Vd with M{it+1} 69 | M{it+1} = contract(diag(S)*Vd,2,2,M{it+1},3,1); 70 | 71 | % % % TODO (end) % % % 72 | end 73 | 74 | % % Bring the right part into the right-canonical form 75 | for it = (numel(M):-1:id+2) 76 | % % % TODO (start) % % % 77 | 78 | % reshape M{it} and SVD 79 | [U,S,M{it},dw(it-1)] = svdTr(M{it},3,1,Nkeep,Skeep); 80 | 81 | % contract U and S with M{it-1} 82 | M{it-1} = contract(M{it-1},3,2,U*diag(S),2,1,[1 3 2]); 83 | 84 | % % % TODO (end) % % % 85 | end 86 | 87 | if id == 0 % purely right-canonical form 88 | [U,S,M{1}] = svdTr(M{1},3,1,[],0); % no trucation 89 | % U is a single number which serves as the overall phase factor to the 90 | % total many-site state. So we can pass over U to M{1}. 91 | M{1} = contract(U,2,2,M{1},3,1); 92 | 93 | elseif id == numel(M) % purely left-canonical form 94 | [M{end},S,Vd] = svdTr(M{end},3,[1 3],[],0); % no trucation 95 | % Vd is a single number which serves as the overall phase factor to the 96 | % total many-site state. So we can pass over Vd to M{end}. 97 | M{end} = contract(M{end},3,3,Vd,2,1,[1 3 2]); 98 | 99 | else % bond-canonical form 100 | T = contract(M{id},3,2,M{id+1},3,1); 101 | [M{id},S,M{id+1},dw(id)] = svdTr(T,4,[1 2],Nkeep,Skeep); 102 | M{id} = permute(M{id},[1 3 2]); 103 | end 104 | 105 | catch e 106 | disp(getReport(e)); 107 | disp('Something got wrong. Debug!') 108 | keyboard 109 | end 110 | 111 | end -------------------------------------------------------------------------------- /Tensor/getIdentity.m: -------------------------------------------------------------------------------- 1 | function A = getIdentity(B,idB,varargin) 2 | % < Description > 3 | % 4 | % # Usage 1 5 | % 6 | % A = getIdentity(B,idB, [,p]) 7 | % 8 | % Obtain the identity tensor in the space of the idB-th leg of B. For 9 | % example, consider a ket tensor B. Then A = getIdentity(B,2) results in: 10 | % 11 | % 1 2 1 2 12 | % -->- B ->--*-->- A ->-- 13 | % | 14 | % 3 ^ 15 | % | 16 | % 17 | % Here the numbers next to the legs mean the order of legs, and * indicates 18 | % the location where the legs will be contracted. 19 | % 20 | % # Usage 2: 21 | % A = getIdentity(B,idB,C,idC [,p]) 22 | % 23 | % Obtain the identity tensor in the direct product space of the Hilbert 24 | % space of the idB-th leg of B and the space of the idC-th leg of C. For 25 | % example, consider a ket tensor B and the identity operator C at local 26 | % site. Then A = getIdentity(B,2,C,2) results in another ket tensor A: 27 | % 28 | % 1 2 1 3 29 | % -->- B ->--*-->- A ->-- 30 | % | | 31 | % 3 ^ 2 ^ 32 | % | | 33 | % * 34 | % 2 ^ 35 | % | 36 | % C 37 | % | 38 | % 1 ^ 39 | % | 40 | % 41 | % < Input > 42 | % B, C : [numeric array] Tensors. 43 | % idB, idC : [integer] Indices for B and C, respectively. 44 | % 45 | % < Option > 46 | % p : [interger array] If the option is given, the identity tensor is 47 | % permuted according to the permutation indices p. 48 | % (Default: not given, i.e., no permutation) 49 | % 50 | % < Output > 51 | % A : [numeric array] Identity tensor. If p option is not given, the 1st 52 | % and 2nd legs of A correspond to the idB-th leg of B and the idC-th 53 | % leg of C, respectively. If the 'p' option is given, the legs are 54 | % permuted accordingly. 55 | % 56 | % Written by S.Lee (May 2, 2017) 57 | % Documentation edited by S.Lee (Sep.08,2022) 58 | % Updated by S.Lee (Mar.03,2024): Fixed a typo in the documentation. 59 | 60 | % parsing input 61 | if nargin > 3 % combine the spaces of two tensors 62 | C = varargin{1}; 63 | idC = varargin{2}; 64 | varargin(1:2) = []; 65 | else % consider only one space 66 | C = []; 67 | idC = []; 68 | end 69 | 70 | % default of options 71 | p = []; % permutation of the contracted tensor (default: no permutation) 72 | 73 | % % % parsing options 74 | while ~isempty(varargin) 75 | if isnumeric(varargin{1}) 76 | p = varargin{1}; 77 | varargin(1) = []; 78 | else 79 | error('ERR: Unkown option.') 80 | end 81 | end 82 | % % % 83 | 84 | DB = size(B,idB); 85 | if ~isempty(C) 86 | DC = size(C,idC); 87 | A = reshape(eye(DB*DC),[DB DC DB*DC]); 88 | else 89 | A = eye(DB); 90 | end 91 | 92 | if ~isempty(p) 93 | if numel(p) < numel(size(A)) 94 | error('ERR: # of elements of permutation option ''p'' is smaller that the rank of ''A''.'); 95 | end 96 | A = permute(A,p); 97 | end 98 | 99 | 100 | end -------------------------------------------------------------------------------- /Tensor/getLocalSpace.m: -------------------------------------------------------------------------------- 1 | function varargout = getLocalSpace (varargin) 2 | % < Description > 3 | % 4 | % [S,I] = getLocalSpace ('Spin',s) % spin 5 | % [F,Z,I] = getLocalSpace ('Fermion') % spinless fermion 6 | % [F,Z,S,I] = getLocalSpace ('FermionS') % spinful (spin-1/2) fermion 7 | % 8 | % Generates the local operators as tensors. The result operators F and S 9 | % are rank-3, whose 1st and 2nd legs are to be contracted with bra and ket 10 | % tensors, respectively. The 3rd legs of F and S encode the flavors of the 11 | % operators, such as spin raising/lowering/z or particle flavor. 12 | % Basis of the output tensors depend on the input as follows: 13 | % * 'Spin',s: +s, +s-1, ..., -s 14 | % * 'Fermion': |vac>, c'|vac> 15 | % * 'FermionS': |vac>, c'_up|vac>, c'_down|vac>, c'_down c'_up|vac> 16 | % Here c' means fermion creation operator. 17 | % 18 | % < Input > 19 | % s : [integer or half-integer] The value of spin (e.g., 1/2, 1, 3/2, ...). 20 | % 21 | % < Output > 22 | % S : [rank-3 tensor] Spin operators. 23 | % S(:,:,1) : spin raising operator S_+ multiplied with 1/sqrt(2) 24 | % S(:,:,2) : spin-z operator S_z 25 | % S(:,:,3) : spin lowering operator S_- multiplied with 1/sqrt(2) 26 | % Then we can construct the Heisenberg interaction ($\vec{S} \cdot 27 | % \vec{S}$) by: contract(S,3,3,conj(S),3,3) that results in 28 | % (S^+ * S^-)/2 + (S^- * S^+)/2 + (S^z * S^z) = (S^x * S^x) + (S^y * 29 | % S^y) + (S^z * S^z). 30 | % There are two advantages of using S^+ and S^- rather than S^x and 31 | % S^y: (1) more compact. For spin-1/2 case for example, S^+ and S^- 32 | % have only one non-zero elements while S^x and S^y have two. (2) We 33 | % can avoid complex number which can induce numerical error and cost 34 | % larger memory; a complex number is treated as two double numbers. 35 | % I : [rank-2 tensor] Identity operator. 36 | % F : [rank-3 tensor] Fermion annihilation operators. For spinless fermions 37 | % ('Fermion'), the 2nd dimension of F is singleton, and F(:,:,1) is 38 | % the annihilation operator. For spinful fermions ('FermionS'), 39 | % F(:,:,1) and F(:,:,2) are the annihilation operators for spin-up 40 | % and spin-down particles, respectively. 41 | % Z : [rank-2 tensor] Jordan-Wigner string operator for anticommutation 42 | % sign of fermions. 43 | % 44 | % Written by S.Lee (May 04,2017) 45 | % Revised by S.Lee (Sep.08,2022) 46 | 47 | % % parsing input 48 | if (numel(varargin) == 0) || ~any(strcmp(varargin{1},{'Spin','Fermion','FermionS'})) 49 | error('ERR: Input #1 should be either ''Spin'', ''Fermion'', or ''FermionS''.'); 50 | end 51 | 52 | switch varargin{1} 53 | case 'Spin' 54 | if nargout > 2 55 | error('ERR: Too many outputs are requested.'); 56 | end 57 | if numel(varargin) < 2 58 | error('ERR: For ''Spin'', input #2 is required.'); 59 | end 60 | s = varargin{2}; 61 | if (abs(2*s - round(2*s)) > eps) || (s <= 0) 62 | error('ERR: Input #2 for ''Spin'' should be positive (half-)integer.'); 63 | end 64 | s = round(2*s)/2; 65 | isFermion = false; 66 | isSpin = true; % create S tensor 67 | I = eye(2*s+1); 68 | case 'Fermion' 69 | if nargout > 3 70 | error('ERR: Too many outputs are requested.'); 71 | end 72 | isFermion = true; % create F and Z tensors 73 | isSpin = false; 74 | I = eye(2); 75 | case 'FermionS' 76 | if nargout > 4 77 | error('ERR: Too many outputs are requested.'); 78 | end 79 | isFermion = true; 80 | isSpin = true; 81 | I = eye(4); 82 | end 83 | % % % 84 | 85 | if isFermion 86 | if isSpin % spinful fermion 87 | % basis: empty, up, down, two (= c_down^+ c_up^+ |vac>) 88 | F = zeros(4,4,2); 89 | % spin-up annihilation 90 | F(1,2,1) = 1; 91 | F(3,4,1) = -1; % -1 sign due to anticommutation 92 | % spin-down annihilation 93 | F(1,3,2) = 1; 94 | F(2,4,2) = 1; 95 | 96 | Z = diag([1 -1 -1 1]); 97 | 98 | S = zeros(4,4,3); 99 | S(2,3,1) = 1/sqrt(2); % spin-raising operator (/sqrt(2)) 100 | S(:,:,3) = S(:,:,1)'; % spin-lowering operator (/sqrt(2)) 101 | % spin-z operator 102 | S(2,2,2) = +1/2; 103 | S(3,3,2) = -1/2; 104 | else % spinless fermion 105 | % basis: empty, occupied 106 | F = zeros(2,2,1); 107 | F(1,2,1) = 1; 108 | 109 | Z = diag([1 -1]); 110 | end 111 | else % spin 112 | % basis: +s, +s-1, ..., -s 113 | Sp = (s-1:-1:-s); 114 | Sp = diag(sqrt((s-Sp).*(s+Sp+1)), 1); % spin raising operator 115 | 116 | Sz = diag(s:-1:-s); % spin-z operator 117 | 118 | S = cat(3,Sp/sqrt(2),Sz,Sp'/sqrt(2)); 119 | end 120 | 121 | % assign the tensors into varargout 122 | if isFermion 123 | if isSpin % spinful fermion 124 | varargout = {F,Z,S,I}; 125 | else % spinless fermion 126 | varargout = {F,Z,I}; 127 | end 128 | else % spin 129 | varargout = {S,I}; 130 | end 131 | 132 | end -------------------------------------------------------------------------------- /Tensor/svdTr.m: -------------------------------------------------------------------------------- 1 | function [U,S,Vd,dw] = svdTr (T,rankT,idU,Nkeep,Skeep) 2 | % < Description > 3 | % 4 | % [U,S,Vd,dw] = svdTr (T,rankT,idU,Nkeep,Skeep) 5 | % 6 | % Singular value decomposition of tensor such that T = U*diag(S)*Vd. (Note 7 | % that it is not U*S*V' as in the MATLAB built-in function 'svd'.) If 8 | % truncation criterion Nkeep or Skeep is given, the tensors are truncated 9 | % to discard the smallest singular values and the corresponding singular 10 | % vectors. 11 | % 12 | % < Input > 13 | % T : [tensor] Tensor. 14 | % rankT : [number] Rank of T. 15 | % idU : [integer vector] Indices of T to be associated with U. For example, 16 | % if rankT == 4 and idU == [1 3], the result U is rank-3 tensor whose 17 | % 1st and 2nd legs correspond to the 1st and 3rd legs of T. The 3rd 18 | % leg of U is associated with the 1st leg of diag(S). And Vd is 19 | % rank-3 tensor whose 2nd and 3rd legs correspond to the 2nd and 4th 20 | % legs of T. Its 1st leg is associated with the 2nd leg of diag(S). 21 | % Nkeep : [number] Maximal number of singular values to keep. If set empty 22 | % ([]), it is interpreted as Inf, meaning no truncation by the number 23 | % of singular values. 24 | % Skeep : [number] Minimum magnitude of the singluar value to keep. If set 25 | % empty ([]), it is interpreted as 10*eps(S(1)), where S(1) means the 26 | % largest singular value. Not to truncate by the magnitude of 27 | % singular values, set Skeep = 0. 28 | % 29 | % < Output > 30 | % U : [tensor] Tensor describing the left singular vectors. Its last leg 31 | % contracts with diag(S). The earlier legs are specified by input 32 | % idU; their order is determined by the ordering of idU. 33 | % S : [vector] The column vector of singular values. If there were no 34 | % truncation, norm(S) indicates the norm of the tensor. 35 | % Vd : [tensor] Tensor describing the right singular vectors. Its 1st leg 36 | % contracts with diag(S). The later legs conserve the order of the 37 | % legs of input T. 38 | % dw : [tensor] Discarded weight (= sum of the square of the singular 39 | % values truncated). 40 | % 41 | % Written by S.Lee (May 22,2017) 42 | % Rewritten by S.Lee (Sep.12,2022) 43 | 44 | % sanity check 45 | if rankT < ndims(T) 46 | error('ERR: Input ''rankT'' is smaller than the rank of other input ''T''.'); 47 | elseif ~all(any(idU(:) == (1:rankT),2)) 48 | error('ERR: Invalid index for tensor U (e.g. out of bound, non-integer).'); 49 | end 50 | 51 | % dimensions of T 52 | Tsz = ones(1,rankT); 53 | Tsz(1:ndims(T)) = size(T); 54 | 55 | % leg indices to be associated with Vd 56 | idV = (1:rankT); 57 | idV(idU) = []; 58 | 59 | % reshape to matrix form 60 | T2 = reshape(permute(T,[idU,idV]),[prod(Tsz(idU)) prod(Tsz(idV))]); 61 | [U2,S2,V2] = svd(T2,'econ'); % SVD 62 | S2 = diag(S2); 63 | 64 | % default truncation parameters 65 | if isempty(Nkeep) 66 | Nkeep = Inf; 67 | end 68 | if isempty(Skeep) && ~isempty(S2) 69 | Skeep = 10*eps(S2(1)); 70 | end 71 | 72 | oks = (S2 >= Skeep); 73 | oks(min(numel(S2),Nkeep)+1:end) = false; 74 | 75 | dw = sum(S2(~oks).^2); 76 | 77 | S = S2(oks); 78 | U = reshape(U2(:,oks),[Tsz(idU) numel(S)]); 79 | Vd = reshape(V2(:,oks)',[numel(S) Tsz(idV)]); 80 | 81 | end -------------------------------------------------------------------------------- /Tutorials/T01.1_MATLAB101/MATLAB101.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.1_MATLAB101/MATLAB101.mlx -------------------------------------------------------------------------------- /Tutorials/T01.1_MATLAB101/MATLAB101.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.1_MATLAB101/MATLAB101.pdf -------------------------------------------------------------------------------- /Tutorials/T01.2_TightBinding/TightBinding.m: -------------------------------------------------------------------------------- 1 | %% Non-interacting fermions on a tight-binding chain 2 | % Author: 3 | %% 4 | % Here we consider non-interacting spinless fermions (or spin-polarized fermions, 5 | % equivalently) on a tight-binding chain. Its Hamiltonian is given by 6 | % 7 | % $$\hat{H} = \sum_{\ell = 1}^{L-1} ( -t_\ell \hat{c}_{\ell+1}^\dagger \hat{c}_{\ell} 8 | % - t_\ell^* \hat{c}_{\ell}^\dagger \hat{c}_{\ell+1} ),$$ 9 | % 10 | % where the chain has $L$ sites, $t_\ell$ indicates the hopping amplitute between 11 | % sites $\ell$ and $\ell+1$, and $\hat{c}_\ell^\dagger$ creates a particle at 12 | % a site $\ell \in [1, L]$. 13 | %% Exercise (a): Compute the energy and degeneracy of the many-body ground states 14 | % Write a script or function that computes the ground-state energy and degeneracy 15 | % of this non-interacting tight-binding chain. The script or function takes the 16 | % following input and output: 17 | % 18 | % *< Input >* 19 | %% 20 | % * |t| : [numeric vector] Each element |t(l)| indicates a hopping amplitude 21 | % $t_\ell$. The length of the vector |numel(t)| equals to the number of chain 22 | % sites minus 1. 23 | %% 24 | % *< Output >* 25 | %% 26 | % * |E_G| : [numeric scalar] Ground-state energy. 27 | % * |d_G| : [numeric scalar] Ground-state degeneracy. 28 | %% 29 | % Once you complete a script or function, compute the ground-state energies 30 | % and degeneracies for the following three cases: 31 | % 32 | % (1) $L = 10$, $t_\ell = 1$ for all $\ell$'s. 33 | % 34 | % (2) $L = 11$, $t_\ell = 1$ for all $\ell$'s. 35 | % 36 | % (3) $L = 11$, $t_\ell = e^{\mathrm{i} \ell}$. -------------------------------------------------------------------------------- /Tutorials/T01.2_TightBinding/TightBinding.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.2_TightBinding/TightBinding.mlx -------------------------------------------------------------------------------- /Tutorials/T01.2_TightBinding/TightBinding.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.2_TightBinding/TightBinding.pdf -------------------------------------------------------------------------------- /Tutorials/T01.2_TightBinding_sol/TightBinding_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Non-interacting fermions on a tight-binding chain 2 | % Author: 3 | %% Solution to Exercise (a): Compute the energy and degeneracy of the many-body ground states 4 | % We introduce a new function |nonIntTB| under under the |Util| directory, which 5 | % computes the ground-state energy and degeneracy as output, taking the hopping 6 | % amplitudes as input. Please read through the function, which is only six lines 7 | % long except for the documentation and comments. You can open the file (i) by 8 | % exploring the "Current Folder" window or (ii) by typing the following command 9 | % in the "Command Window": 10 | 11 | edit nonIntTB.m 12 | %% 13 | % If you see an error message that MATLAB cannot find file or directory, please 14 | % re-run |startup.m|. The shortcut on the upper-right corner (which you created 15 | % by following |readme.[pdf,mlx]|) is very convenient in this regard! 16 | % 17 | % The function will be used later during the course. To remind yourself of its 18 | % usage then, you can type the following in the "Command Window": 19 | 20 | help nonIntTB 21 | %% 22 | % The function implements the single-particle Hamiltonian, 23 | % 24 | % $H = \sum_{\ell=1}^{L-1} -t_\ell |\ell+1\rangle\!\langle \ell | - t_\ell^* 25 | % |\ell\rangle\!\langle\ell+1|$, 26 | % 27 | % as a matrix, 28 | % 29 | % 30 | % 31 | % The rows (columns) of the matrix are associated with kets $\{ |\ell\rangle 32 | % \}$ (bras $\{\langle \ell |\}$). The first diagonal _below_ the main diagonal 33 | % is filled with $\{ -t_\ell \}$ that represent "forward" hoppings, i.e., moving 34 | % to the sites with larger indices, while the first diagonal _above_ the main 35 | % diagonal is with $\{ -t_\ell^* \}$ for "backward" hoppings. 36 | % 37 | % After diagonalizing the matrix, a tolerance is set so that its eigenvalues 38 | % (i.e., the single-particle eigen-energies) whose magnitudes are smaller than 39 | % the tolerance are replaced by zeros. The tolerance is defined in terms of double 40 | % precision, using |eps|. 41 | %% 42 | % With the function, we can easily solve the sub-exercises by only replacing 43 | % the input to the function. 44 | % (1) $L = 10$, $t_\ell = 1$ for all $\ell$'s: 45 | 46 | [E_G,d_G,e_1p] = nonIntTB (ones(9,1)); 47 | fprintf('E_G = %.4g, d_G = %i\n',E_G,d_G); 48 | %% 49 | % We find that the single-particle eigen-energies, |e_1p|, has a symmetry such 50 | % that all elements have their opposite-sign partners within the array. 51 | 52 | e_1p 53 | e_1p + flip(e_1p,1) % zeros up to numerical precision 54 | %% 55 | % Such symmetry is called particle-hole symmetry. Non-interacting tight-binding 56 | % chains are particle-hole symmetric when there are only nearest-neighbor hoppings, 57 | % without on-site energies and long-range hoppings. This statement can be simply 58 | % proven by applying the particle-hole transformation, $\hat{c}_\ell \mapsto (-1)^{\ell+1} 59 | % \hat{h}_\ell^\dagger$, where $\hat{h}_\ell^\dagger$ creates a "hole" at site 60 | % $\ell$. Then the Hamiltonian becomes 61 | % 62 | % $$\hat{H} [\{ \hat{h}_\ell, \hat{h}_\ell^\dagger \}] = \sum_{\ell = 1}^{L-1} 63 | % ( -t_\ell \hat{h}_{\ell+1}^\dagger \hat{h}_{\ell} - t_\ell^* \hat{h}_{\ell}^\dagger 64 | % \hat{h}_{\ell+1} ),$$ 65 | % 66 | % which is basically identical to the original Hamiltonian, except that it's 67 | % written in $h$'s instead of $c$'s. So the energy eigenvalues of the "hole" Hamiltonian 68 | % $\hat{H} [\{ \hat{h}_\ell, \hat{h}_\ell^\dagger \}]$ equals to those of the 69 | % original Hamiltonian, indicating that hole excitations have the same energies 70 | % as particle excitations. Note that hole excitations mean emptying out the single-particle 71 | % levels below 0 (that were filled in the ground-state configurations), while 72 | % particle excitations filling up the levels above 0 (that were empty in the ground-state 73 | % configurations). 74 | % (2) $L = 11$, $t_\ell = 1$ for all $\ell$'s: 75 | 76 | [E_G,d_G,e_1p] = nonIntTB (ones(10,1)); 77 | fprintf('E_G = %.4g, d_G = %i\n',E_G,d_G); 78 | %% 79 | % Now we have the groud-state degneracy, since there is a zero element in |e_1p|: 80 | 81 | e_1p 82 | % (3) $L = 11$, $t_\ell = e^{\mathrm{i} \ell}$: 83 | 84 | [E_G,d_G,e_1p] = nonIntTB (exp(1i*(1:10).')); 85 | fprintf('E_G = %.4g, d_G = %i\n',E_G,d_G); 86 | %% 87 | % The values of |E_G| and |d_G| equal to those of the above sub-exercise (2). 88 | % It is because the phase factors in $\{ t_\ell \}$ can be absorbed into the definition 89 | % of the single-particle bases $\{ | \ell \rangle \}$. Such absorption is possible 90 | % since hoppings are only between nearest neighbors. In the second quantization 91 | % language, we consider the transformation $\hat{c}_\ell \mapsto e^{-\mathrm{i} 92 | % \ell (\ell-1)/2} \hat{c}_\ell$ after which the Hamiltonian becomes the same 93 | % as one with $t_\ell = 1$ for all $\ell$'s. -------------------------------------------------------------------------------- /Tutorials/T01.2_TightBinding_sol/TightBinding_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.2_TightBinding_sol/TightBinding_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T01.2_TightBinding_sol/TightBinding_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.2_TightBinding_sol/TightBinding_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T01.3_SVD_Example/Gwanghwamun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.3_SVD_Example/Gwanghwamun.jpg -------------------------------------------------------------------------------- /Tutorials/T01.3_SVD_Example/SVD_Example.m: -------------------------------------------------------------------------------- 1 | %% SVD Example: Image compression 2 | % Author: 3 | %% 4 | % We will provide a visual understanding of how the SVD can be used to compress 5 | % large matrices. First load a sample image data of _Gwanghwamun_ (광화문), retrived 6 | % from a . 8 | 9 | clear 10 | 11 | M = imread('Gwanghwamun.jpg'); % Read image data from a picture 12 | %% 13 | % To see the information of variables, type: 14 | 15 | whos M 16 | %% 17 | % If you use graphic interface, just look the workspace panel which is usually 18 | % on the upper-right corner of the MATLAB main window. We see that |M| is 2730 19 | % $\times$ 4855 $\times$ 3 matrix of |uint8| type. The first and second dimensions 20 | % of |M| indicates the height and width of the photo, and the third dimension 21 | % encodes RGB data. As |uint8| is unsigned integer each occupying 8 bit (= 1 byte) 22 | % of memory. Therefore, |M| is about 10 MB! 23 | %% Visualization of matrix 24 | % MATLAB provides several functions to visualize matrices. 25 | 26 | figure; % open new figure window 27 | imshow(M); % display image with matrix of uint8 type (NOT double). 28 | %% 29 | % |imshow| does not work for double type variables (which are generally used 30 | % in MATLAB calculations). So for general purpooses, use |imagesc| as below. 31 | 32 | figure; 33 | imagesc(M); % display image with axes. 34 | %% 35 | % Note that the height-to-width ratio of pictures by |imshow| is the same as 36 | % the original picture, but the ratio of pictures by |imagesc| is fitted to the 37 | % figure window size. 38 | % 39 | % For the rest of this tutorial, we will make |M| as a matrix, by converting 40 | % it to double and sum over the third dimension. 41 | 42 | M = double(M); % convert data type: uint8 -> double 43 | M = sum(M,3); % sum over the 3rd dim. 44 | %% SVD of picture data 45 | 46 | [U,S,V] = svd(M); % singular value decomposition 47 | %% 48 | % To see the distribution of the singular values, we plot them. 49 | 50 | figure; 51 | plot(diag(S),'LineWidth',1); % plot diagonal elements of S. 52 | set(gca,'LineWidth',1,'FontSize',13) 53 | title('Singluar values'); % add title 54 | ylabel('Magnitude'); % add y-axis label 55 | grid on; % turn on grid line 56 | %% 57 | % The magnitude of the singluar values decays exponentially. To better see the 58 | % exponential decay, plot in log-linear scale. 59 | 60 | figure; 61 | semilogy(diag(S),'LineWidth',1); % plot diagonal elements of S. 62 | set(gca,'LineWidth',1,'FontSize',13) 63 | title('Singluar values'); % add title 64 | ylabel('Magnitude'); % add y-axis label 65 | grid on; % turn on grid line 66 | %% Reconstruction of picture 67 | % Now we reconstruct picture from the SVD result of |M|. It is clear that |U*S*V'| 68 | % will return the same matrix as |M| (up to double precision $\sim$1e-16). But 69 | % what if we use only the parts of |U|, |S|, and |V|? Based on the exponential 70 | % decay of the singular values, we can think of an approach that keeps only some 71 | % of the largest singular values and the corresponding singular vectors. 72 | % 73 | % Let's compare how pictures will look like with different number of kept singular 74 | % values. 75 | 76 | Nkeep = [10,30,100,300]; % different number of singular values to keep 77 | 78 | Ms = cell(numel(Nkeep),1); % cell array to contain matrices 79 | 80 | for it = (1:numel(Nkeep)) 81 | Ms{it} = U(:,1:Nkeep(it))*S(1:Nkeep(it),1:Nkeep(it))*V(:,1:Nkeep(it))'; 82 | 83 | figure; 84 | imagesc(Ms{it}); 85 | colormap(gray); 86 | set(gca,'FontSize',13) 87 | title([sprintf('%i',Nkeep(it)),' singluar values are kept']); 88 | end 89 | %% 90 | % Only with 30 singular values, the rough shape of the building is already visible. 91 | % With 100 singular values (about 3.7% of total singular values), we can recognize 92 | % the name (光化門) on the signboard and distinguish pedestrians. Of course, if you 93 | % zoom in, you will realize that sharp details, such as the roof on the left wall, 94 | % can be properly resolved by taking 300 singular values. 95 | %% Exercise (a): Understanding singular vectors 96 | % From the demonstration above, we have found that the singular vectors for 97 | % the largest singular values (e.g. |U(:,(1:10))| and |V(:,(1:10))|) contribute 98 | % more to the original matrix |M| than the singular vectors for the smallest singular 99 | % values (e.g. |U(:,(end-9:end))| and |V(:,(end-9:end))|). Can you find the qualitative 100 | % differences between the vectors for the largest singular values and the vectors 101 | % for the smallest singular values? Use |fft| (Fast Fourier transform) for analyzing 102 | % the vectors. The exercise is designed to make students familiar with reading 103 | % and understanding MATLAB documentation. If you didn't read the documentation 104 | % for |fft|, please read it through to the end. -------------------------------------------------------------------------------- /Tutorials/T01.3_SVD_Example/SVD_Example.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.3_SVD_Example/SVD_Example.mlx -------------------------------------------------------------------------------- /Tutorials/T01.3_SVD_Example/SVD_Example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.3_SVD_Example/SVD_Example.pdf -------------------------------------------------------------------------------- /Tutorials/T01.3_SVD_Example_sol/SVD_Example_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.3_SVD_Example_sol/SVD_Example_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T01.3_SVD_Example_sol/SVD_Example_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T01.3_SVD_Example_sol/SVD_Example_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T02.1_Wstate/Wstate.m: -------------------------------------------------------------------------------- 1 | %% W state 2 | % Author: 3 | %% 4 | % In quantum information theory, there are several special quantum states. One 5 | % among them is the W state. The $N$-qubit W state is defined by the equal superposition 6 | % of all possible pure states in which exactly one of the qubits is in the $|1\rangle$ 7 | % state and the rest are in the $|0\rangle$ state: 8 | % 9 | % $$|\mathrm{W}\rangle = \frac{1}{\sqrt{N}} ( |1 0 0 \cdots 0 0 \rangle + |0 10 | % 1 0 \cdots 0 0\rangle + \cdots + | 0 0 0 \cdots 0 1\rangle).$$ 11 | % 12 | % The W state is named after *W*olfgang Dür, an Austrian physicist who proposed 13 | % the W state for three qubits, together with Guifré Vidal and J. Ignacio Cirac 14 | % in []. You will see 16 | % the latter two authors' names often during this lecture course, as they are 17 | % early founders of tensor networks! 18 | % 19 | % The $N$-qubit W state can be represented in terms of a rank-$N$ tensor $A$, 20 | % 21 | % $$| \mathrm{W} \rangle = | n_1 n_2 \cdots n_N \rangle A^{n_1+1, n_2+1, \cdots, 22 | % n_N + 1},$$ 23 | % 24 | % where $n_i = 0,1$ indicate the state of the $i$-th qubit, associated with 25 | % indices 1 and 2, respectively, along the $i$-th dimension of the tensor $A$. 26 | % The repeated indices $n_1, \cdots, n_N$ are assumed to be summed over. 27 | %% Exercise (a): Tensor representation of the W state 28 | % Write a script or function that generate the rank-$n$ tensor $A$, taking a 29 | % general input of $N$. Try to compose it in the most compact way, while keeping 30 | % its computational efficiency. -------------------------------------------------------------------------------- /Tutorials/T02.1_Wstate/Wstate.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.1_Wstate/Wstate.mlx -------------------------------------------------------------------------------- /Tutorials/T02.1_Wstate/Wstate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.1_Wstate/Wstate.pdf -------------------------------------------------------------------------------- /Tutorials/T02.1_Wstate_sol/Wstate_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] W state 2 | % Author: 3 | %% Solution to Exercise (a): Tensor representation of the W state 4 | % The tensor representation of the W state for a general qubit number $N$ can 5 | % be generated with just two lines of code! 6 | 7 | A = zeros(2*ones(1,N)); % define a rank-N tensor 8 | A(2.^(0:N-1)+1) = 1/sqrt(N); % assign coefficients 9 | %% 10 | % Let's check whether it works. 11 | 12 | N = 5; 13 | A = zeros(2*ones(1,N)); 14 | A(2.^(0:N-1)+1) = 1/sqrt(N); 15 | nnz(A) % number of nonzero elements 16 | A(2,1,1,1,1)*sqrt(N) 17 | A(1,2,1,1,1)*sqrt(N) 18 | A(1,1,2,1,1)*sqrt(N) 19 | A(1,1,1,2,1)*sqrt(N) 20 | A(1,1,1,1,2)*sqrt(N) -------------------------------------------------------------------------------- /Tutorials/T02.1_Wstate_sol/Wstate_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.1_Wstate_sol/Wstate_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T02.1_Wstate_sol/Wstate_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.1_Wstate_sol/Wstate_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T02.2_TensorContraction/TensorContraction.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.2_TensorContraction/TensorContraction.mlx -------------------------------------------------------------------------------- /Tutorials/T02.2_TensorContraction/TensorContraction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.2_TensorContraction/TensorContraction.pdf -------------------------------------------------------------------------------- /Tutorials/T02.2_TensorContraction_sol/TensorContraction_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.2_TensorContraction_sol/TensorContraction_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T02.2_TensorContraction_sol/TensorContraction_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T02.2_TensorContraction_sol/TensorContraction_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T03.1_TensorDecomposition/TensorDecomposition.m: -------------------------------------------------------------------------------- 1 | %% Tensor decomposition and entanglement entropy 2 | % Author: 3 | %% 4 | % In this tutorial, we will decompose a high-rank tensor into a matrix product 5 | % state (MPS) that consists of rank-2 and -3 tensors, by using the QR decomposition 6 | % or the singular value decomposition (SVD). 7 | % 8 | % Let's define a rank-5 tensor acting onto five subsystems, whose dimensions 9 | % are 2, 3, 2, 3, and 4, respectively. 10 | 11 | clear 12 | sz = [2 3 2 3 4]; % local space dimensions 13 | T = reshape((1:prod(sz)),sz); % rank-5 tensor 14 | T = T/norm(T(:)); % normalize 15 | %% 16 | % Here |T| is normalized by its norm. Note that, for the computation of the 17 | % norm, it's necessary to take a linearized form of the tensor by using |(:)|. 18 | % 19 | % I will demonstrate the decomposition of the tensor "from left to right", i.e., 20 | % decomposing a tensor for the first leg, then for the second, and so on, by using 21 | % the QR decomposition: 22 | % 23 | % 24 | % 25 | % The numbers next to the tensor legs indicate the order of the legs. A left-unitary 26 | % matrix obtained after the $n$-th QR decomposition are reshaped and stored in 27 | % the $n$-th cell |Q{n}|. At the last iteration (i.e., the fourth iteration), 28 | % we dump the remaining tensor into |Q{5}|. For |Q{1}| and |Q{5}|, we assign the 29 | % dummy legs of dimension 1, indicated by the x symbols at the ends. By introducing 30 | % the dummy legs, we can treat all the tensors |Q{n}| as rank-3, which simplifies 31 | % the code writing. 32 | 33 | Q = cell(1,numel(sz)); 34 | R = T; % temporary tensor to be QR-decomposed 35 | szl = 1; % the bond dimension of the left leg of Q{n} to be obtained after 36 | % the QR decomposition at iteration n; for n = 1, szl = 1 for the dummy leg 37 | for it = (1:(numel(sz)-1)) 38 | R = reshape(R,[szl*sz(it), prod(sz(it+1:end))]); 39 | [Q{it},R] = qr(R,0); 40 | Q{it} = reshape(Q{it},[szl, sz(it), numel(Q{it})/szl/sz(it)]); 41 | Q{it} = permute(Q{it},[1 3 2]); % permute to the left-right-bottom order 42 | szl = size(Q{it},2); % update the bond dimension 43 | R = reshape(R,[szl,sz(it+1:end)]); 44 | end 45 | Q{end} = permute(R,[1 3 2]); 46 | %% 47 | % Note we use the thin QR decomposition by setting the second input argument 48 | % to |qr| as |0|. 49 | % 50 | % Check the dimensions of tensors in the MPS. 51 | 52 | Q 53 | %% 54 | % Note that the MATLAB automatically truncates the trailing singleton dimension, 55 | % so the dummy leg dimension of |Q{5}| is not displayed. 56 | %% Exercise (a): Check the integrity of the tensor decomposition 57 | % Contract the tensors |Q{1}|, ..., |Q{5}| to make a rank-5 tensor again. Check 58 | % whether the contraction result is the same as the original tensor |T|. 59 | %% Exercise (b): Entanglement entropies for different bipartitions 60 | % Compute the entanglement entropy $S_{\mathrm{A}/\mathrm{B}}$ for the following 61 | % three ways of bipartitioning the tensor |T|'s fives legs into two sets, A and 62 | % B: 63 | % 64 | % (i) A = {1, 2}, B = {3, 4, 5}; 65 | % 66 | % (ii) A = {1, 3}, B = {2, 4, 5}; 67 | % 68 | % (iii) A = {1, 5}, B = {2, 3, 4}. 69 | %% Exercise (c): Use the SVD for the tensor decomposition and compute the entanglement entropy 70 | % Let's consider the same tensor |T| defined above. Apply the series of the 71 | % SVD from left to right to decompose |T| into an MPS, represented by a cell array 72 | % |M|. 73 | %% 74 | % # At each step $n$ of the SVD, compute the entanglement entropy $S_n = - \sum_i 75 | % s_i^2 \log_2 (s_i^2)$ by using the singular values $\{ s_i \}$. What are the 76 | % values of $S_n$ for different iterations? 77 | % # After the SVD, truncate the decomposed components associated with the singular 78 | % values smaller than the double precision accuracy limit |eps|. How do the size 79 | % of tensors |M{n}| differ from the above results |Q{n}|? 80 | % # Similarly as in Exercise (a), check whether the contraction of |M{n}|'s 81 | % reproduce the original tensor |T|. -------------------------------------------------------------------------------- /Tutorials/T03.1_TensorDecomposition/TensorDecomposition.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T03.1_TensorDecomposition/TensorDecomposition.mlx -------------------------------------------------------------------------------- /Tutorials/T03.1_TensorDecomposition/TensorDecomposition.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T03.1_TensorDecomposition/TensorDecomposition.pdf -------------------------------------------------------------------------------- /Tutorials/T03.1_TensorDecomposition_sol/TensorDecomposition_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T03.1_TensorDecomposition_sol/TensorDecomposition_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T03.1_TensorDecomposition_sol/TensorDecomposition_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T03.1_TensorDecomposition_sol/TensorDecomposition_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T04.1_DiagHamiltonian/DiagHamiltonian.m: -------------------------------------------------------------------------------- 1 | %% Diagonalize many-body Hamiltonians 2 | % Author: 3 | %% 4 | % In this tutorial, we will construct many-body Hamiltonians by using tensor 5 | % networks and diagonalize them. We introduce two new functions that perform the 6 | % tasks needed in this tutorial. 7 | %% 8 | % * |Tensor/getIdentity.m|: It creates a rank-2 identity tensor that spans the 9 | % space of a specified leg of an input tensor, or a rank-3 identity tensor that 10 | % merge two specified legs of input tensors. 11 | % * |Tensor/getLocalSpace.m|: It generates local operators for spins, spinless 12 | % fermions, and spinful fermions. 13 | %% 14 | % Check out the documentation of these functions for details. 15 | %% Exercise (a): Spin-1/2 Heisenberg triangle (pen-and-paper) 16 | % In Exercises (a) and (b), we study the system of three spin-1/2's, where every 17 | % pair of spins interact via the Heisenberg exchange of equal strength. The system's 18 | % Hamiltonian is specified as 19 | % 20 | % $$\hat{H} = J (\hat{\vec{S}}_1 \cdot \hat{\vec{S}}_2 + \hat{\vec{S}}_1 \cdot 21 | % \hat{\vec{S}}_3 + \hat{\vec{S}}_2 \cdot \hat{\vec{S}}_3).$$ 22 | % 23 | % Identify the eigenvalues and their degeneracies of the Hamiltonian by hand. 24 | % 25 | % (_Hint_: By exploting the SU(2) spin symmetry, the Hamiltonian can be much 26 | % simplified.) 27 | %% Exercise (b): Spin-1/2 Heisenberg triangle (coding) 28 | % In this Exercise, we solve the Hamiltonian introduced in Exercise (a) above, 29 | % with $J = 1$. Obtain the matrix elements of the Hamiltonian in the many-body 30 | % state basis, by constructing the identity tensors (without trunctating them) 31 | % and contracting them with spin operators. Then diagonalize the Hamiltonian to 32 | % obtain the energy eigenvalues. Check whether your numerical result is consistent 33 | % with pen-and-paper calculations done for Exercise (a) above. 34 | %% Exercise (c): Non-interacting tight-binding chain 35 | % In this Exercise, we consider non-interacting spinless fermions (or spin-polarized 36 | % fermions, equivalently) on a tight-binding chain. Its Hamiltonian is given by 37 | % 38 | % $$\hat{H} = \sum_{\ell = 1}^{N-1} ( -t_\ell \hat{c}_{\ell+1}^\dagger \hat{c}_{\ell} 39 | % - t_\ell^* \hat{c}_{\ell}^\dagger \hat{c}_{\ell+1} ),$$ 40 | % 41 | % where the chain has $N$ sites, $t_\ell$ indicates the hopping amplitute between 42 | % sites $\ell$ and $\ell+1$, and $\hat{c}_\ell^\dagger$ creates a particle at 43 | % a site $\ell \in [1, N]$. Consider the case of $N = 11$ and $t_\ell = e^{\mathrm{i} 44 | % \ell}$. Obtain the matrix elements of the Hamiltonian in the many-body state 45 | % basis (without truncation), and diagonalize it to identify the ground-state 46 | % and the lowest-excited-state energies and their degeneracies. Compare your "many-body 47 | % calculation" result with one from |Util/nonIntTB.m|. -------------------------------------------------------------------------------- /Tutorials/T04.1_DiagHamiltonian/DiagHamiltonian.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T04.1_DiagHamiltonian/DiagHamiltonian.mlx -------------------------------------------------------------------------------- /Tutorials/T04.1_DiagHamiltonian/DiagHamiltonian.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T04.1_DiagHamiltonian/DiagHamiltonian.pdf -------------------------------------------------------------------------------- /Tutorials/T04.1_DiagHamiltonian_sol/DiagHamiltonian_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T04.1_DiagHamiltonian_sol/DiagHamiltonian_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T04.1_DiagHamiltonian_sol/DiagHamiltonian_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T04.1_DiagHamiltonian_sol/DiagHamiltonian_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T05.1_IterativeDiag/IterativeDiag.m: -------------------------------------------------------------------------------- 1 | %% Iterative diagonalization 2 | % Author: 3 | %% 4 | % The Hilbert space dimension of a many-body system increases exponentially 5 | % with the number of single-particle bases (e.g., number of lattice/chain sites). 6 | % To keep the tensor size manageable, tensor-networks-based methods use various 7 | % ways to truncate the Hilbert space. 8 | % 9 | % Iterative diagonalization is such an approach. Let's consider a one-dimensional 10 | % system having $N$ sites. At the $n$-th iteration of iterative diagonalization, 11 | % we diagonalize the Hamiltonian of the subsystem ranging from site 1 to site 12 | % $n$. The $N_\mathrm{keep}$ (and a few more) lowest-lying energy eigenvalues 13 | % and the corresponding eigenstates are kept to span the Hilbert space for the 14 | % enlarged subsystem, ranging from site 1 to site $n+1$, to be treated at the 15 | % next iteration. 16 | % 17 | % Here we need to *keep all degenerate states whose energies are close to the 18 | % truncation threshold.* So the actual number of kept states at an iteration can 19 | % be larger than $N_\mathrm{keep}$, hence "a few more". The closeness to the threshold 20 | % is determined by the tolerance parameter |tol|, chosen in terms of numerical 21 | % precision; the states separated within this tolerance are regarded as degenerate. 22 | % The degeneracy often comes from physical symmetries, such as spin and particle-hole 23 | % symmetries. If we keep only the part of the degenerate states, then the Hilbert 24 | % space will not respect the symmetries anymore. This artificial symmetry breaking 25 | % would lead to qualitatively wrong result. (Of course, we can discard the degenerate 26 | % states altogether, rather than keeping them, which also preserves the symmetries.) 27 | %% Exercise (a): Non-interacting tight-binding chain 28 | % In this Exercise, we implement iterative diagonalization codes for computing 29 | % the ground-state energy of non-interacting spinless fermions on a tight-binding 30 | % chain. Since it's non-interacting, we can compare the iterative diagonalization 31 | % results with numerically exact single-particle calculations (namely, via |nonIntTB|). 32 | % The Hamiltonian is given by 33 | % 34 | % $$\hat{H} = \sum_{\ell = 1}^{N-1} ( -t_\ell \hat{c}_{\ell+1}^\dagger \hat{c}_{\ell} 35 | % - t_\ell^* \hat{c}_{\ell}^\dagger \hat{c}_{\ell+1} ),$$ 36 | % 37 | % where the chain has $N$ sites and $\hat{c}_\ell^\dagger$ creates a particle 38 | % at a site $\ell \in [1, N]$. Here we consider two different chain types (i) 39 | % with uniform hopping amplitudes, $t_\ell = 1$, and (ii) with logarithmic hopping 40 | % amplitudes, $t_\ell = 2^{-(\ell-1)/2}$. Compute the ground-state energies of 41 | % both types for various chain lengths, $N = 2, 3, \cdots, 50$, and compare them 42 | % the single-particle calculations. Use $N_\mathrm{keep} = 300$. -------------------------------------------------------------------------------- /Tutorials/T05.1_IterativeDiag/IterativeDiag.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.1_IterativeDiag/IterativeDiag.mlx -------------------------------------------------------------------------------- /Tutorials/T05.1_IterativeDiag/IterativeDiag.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.1_IterativeDiag/IterativeDiag.pdf -------------------------------------------------------------------------------- /Tutorials/T05.1_IterativeDiag_sol/IterativeDiag_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Iterative diagonalization 2 | % Author: 3 | %% Solution to Exercise (a): Non-interacting tight-binding chain 4 | % The results for both chain types can be obtained within a single code block, 5 | % by making a for-loop. 6 | 7 | clear 8 | 9 | N = 50; % maximum chain length 10 | 11 | ts = {ones(1,N-1), ... % uniform hopping 12 | 2.^(-(0:N-2)/2)}; % logarithmic hopping 13 | 14 | % titles for plots; see below 15 | strs = {'Uniform hopping', ... 16 | 'Logarithmic hopping'}; 17 | 18 | Nkeep = 300; 19 | tol = Nkeep*100*eps; % numerical tolerance for degeneracy 20 | 21 | [F,Z,I] = getLocalSpace('Fermion'); 22 | 23 | for itE = (1:numel(ts)) 24 | % tensors for the vaccum (i.e., dummy leg) 25 | Hprev = 0; % initialize Hamiltonian 26 | Aprev = 1; % identity tensor for the dummy leg 27 | 28 | % ground-state energies for different lengths 29 | E0_iter = zeros(1,N); % iterative diagonalization result 30 | E0_exact = zeros(1,N); % single-particle result 31 | 32 | for itN = (1:N) 33 | % add new site 34 | Anow = getIdentity(Aprev,2,I,2,[1 3 2]); 35 | Hnow = updateLeft(Hprev,2,Anow,[],[],Anow); 36 | % update the Hamiltonian up to the last sites 37 | % to the enlarged Hilbert space 38 | 39 | if itN > 1 40 | % add hoping terms 41 | ZF = contract(Z,2,2,F,3,1); 42 | Hhop = (-ts{itE}(itN-1))*updateLeft(Fprev,3,Anow, ... 43 | permute(conj(ZF),[2 1 3]),3,Anow); 44 | % hopping from the last site to the current site 45 | 46 | Hnow = Hnow + Hhop + Hhop'; 47 | end 48 | 49 | [V,D] = eig((Hnow+Hnow')/2); 50 | % sort eigenvalues and eigenvectors in the order of increasing 51 | % eigenvalues 52 | [D,ids] = sort(diag(D),'ascend'); 53 | V = V(:,ids); 54 | 55 | E0_iter(itN) = D(1); 56 | 57 | % truncation threshold for energy 58 | Etr = D(min([numel(D);Nkeep])); 59 | oks = (D < (Etr + tol)); 60 | % true: to keep, false: not to keep 61 | % keep all degenerate states up to tolerance 62 | 63 | Aprev = contract(Anow,3,2,V(:,oks),2,1,[1 3 2]); 64 | Hprev = diag(D(oks)); % vector -> diagonal matrix 65 | 66 | % update operator for the next iteration 67 | Fprev = updateLeft([],[],Aprev,F,3,Aprev); 68 | 69 | % exact solution by diagonalizing the single-particle Hamiltonian 70 | if itN > 1 71 | E0_exact(itN) = nonIntTB(ts{itE}(1:itN-1)); 72 | end 73 | 74 | disptime(['#',sprintf('%02i/%02i',[itN,N]),' : ', ... 75 | 'NK=',sprintf('%i/%i',[size(Aprev,2),size(Anow,2)])]); 76 | end 77 | figure; 78 | hold on; 79 | plot((1:N),E0_iter-E0_exact,'LineWidth',1,'LineStyle','-'); 80 | hold off; 81 | set(gca,'LineWidth',1,'FontSize',13); 82 | xlabel('Chain length'); 83 | ylabel('Ground-state energy error'); 84 | grid on; 85 | title(strs{itE}); 86 | end 87 | %% 88 | % We find that iterative diagonalization results for uniform hopping case exhibit 89 | % errors increasing with chain length, while being highly accurate for logarithmic 90 | % hopping case. Indeed, the latter forms the basis of the numerical renormalization 91 | % group (NRG), which is the gold standard method for solving quantum impurity 92 | % problems. NRG will be covered in detail later this course. -------------------------------------------------------------------------------- /Tutorials/T05.1_IterativeDiag_sol/IterativeDiag_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.1_IterativeDiag_sol/IterativeDiag_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T05.1_IterativeDiag_sol/IterativeDiag_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.1_IterativeDiag_sol/IterativeDiag_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T05.2_CanonicalForm/CanonicalForm.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.2_CanonicalForm/CanonicalForm.mlx -------------------------------------------------------------------------------- /Tutorials/T05.2_CanonicalForm/CanonicalForm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.2_CanonicalForm/CanonicalForm.pdf -------------------------------------------------------------------------------- /Tutorials/T05.2_CanonicalForm/canonForm_Ex.m: -------------------------------------------------------------------------------- 1 | function [M,S,dw] = canonForm_Ex (M,id,Nkeep,Skeep) 2 | % < Description > 3 | % 4 | % [M,S,dw] = canonForm_Ex (M,id,Nkeep,Skeep); 5 | % 6 | % Obtain the canonical forms of MPS, depending on the index id of the 7 | % target bond. The left part of the MPS, M{1}, ..., M{id}, is brought into 8 | % the left-canonical form and the right part of the MPS; M{id+1}, ..., 9 | % M{end}, into the right-canonical form. Thus, if id is 0, the result is 10 | % purely right-canonical form; if id is numel(M), the result is purely 11 | % left-canonical form. 12 | % 13 | % < Input > 14 | % M : [cell array] MPS of length numel(M). Each cell element is a rank-3 15 | % tensor, where the first, second, and third dimensions are 16 | % associated with left, right, and bottom (i.e., physical) legs, 17 | % respectively. 18 | % id : [integer] Index for the bond connecting the tensors M{id} and 19 | % M{id+1}. With respect to the bond, the tensors to the left 20 | % (right) are brought into the left-(right-)canonical form. 21 | % Nkeep : [number] Maximal number of singular values to keep at each SVD. 22 | % If set empty ([]), it is interpreted as Inf, meaning no truncation 23 | % by the number of singular values. 24 | % Skeep : [number] Minimum magnitude of the singluar value to keep at each 25 | % SVD. If set empty ([]), it is interpreted as 10*eps(S(1)), where 26 | % S(1) means the largest singular value. Not to truncate by the 27 | % magnitude of singular values, set Skeep = 0. 28 | % 29 | % < Output > 30 | % M : [cell array] Left-, right-, or bond-canonical form from input M, 31 | % depending on id, as follows: 32 | % * id == 0: right-canonical form 33 | % * id == numel(M): left-canonical form 34 | % * otherwise: bond-canonical form 35 | % S : [column vector] Singular values at the bond between M{id} and M{id+1} 36 | % if 0 < id < numel(M); the norm of the MPS if id = 1 or numel(M). 37 | % dw : [column vector] Vector of length numel(M)-1. dw(n) means the 38 | % discarded weight (i.e., the sum of the square of the singular 39 | % values that are discarded) at the bond between M{n} and M{n+1}. 40 | % 41 | % Written by S.Lee (Apr.30,2019) 42 | % Rewritten by S.Lee (Sep.12,2022) 43 | 44 | try 45 | 46 | % % check the integrity of input 47 | if (numel(id) ~= 1) || (round(id) ~= id) 48 | error('ERR: 2nd input ''id'' needs to be a single integer.'); 49 | elseif (id < 0) || (id > numel(M)) 50 | error('ERR: the 2nd input ''id'' needs to be in a range (0:numel(M))'); 51 | elseif size(M{1},1) ~= 1 52 | error('ERR: the first dimension (= left leg) of M{1} should be of size 1.'); 53 | elseif size(M{end},2) ~= 1 54 | error('ERR: the second dimension (= right leg) of M{end} should be of size 1.'); 55 | end 56 | % % % % 57 | 58 | dw = zeros(numel(M)-1,1); % discarded weights 59 | 60 | % % % TODO (start) % % % 61 | 62 | % % Bring the left part of MPS into the left-canonical form 63 | for it = (1:id-1) 64 | 65 | % reshape M{it} and SVD 66 | 67 | 68 | % contract S and Vd with M{it+1} 69 | 70 | 71 | end 72 | 73 | % % Bring the right part into the right-canonical form 74 | for it = (numel(M):-1:id+2) 75 | % % % TODO (start) % % % 76 | 77 | % reshape M{it} and SVD 78 | 79 | 80 | % contract U and S with M{it-1} 81 | 82 | 83 | end 84 | 85 | 86 | if id == 0 % purely right-canonical form 87 | % no trucation in SVD 88 | 89 | % U is a single number which serves as the overall phase factor to the 90 | % total many-site state. So we can pass over U to M{1}. 91 | 92 | elseif id == numel(M) % purely left-canonical form 93 | % no trucation in SVD 94 | 95 | % V' is a single number which serves as the overall phase factor to the 96 | % total many-site state. So we can pass over V' to M{end}. 97 | 98 | else % bond-canonical form 99 | % SVD with truncation 100 | 101 | end 102 | 103 | % % % TODO (end) % % % 104 | 105 | catch e 106 | disp(getReport(e)); 107 | disp('Something got wrong. Debug!') 108 | keyboard 109 | end 110 | 111 | end -------------------------------------------------------------------------------- /Tutorials/T05.2_CanonicalForm_sol/CanonicalForm_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Canonical forms of MPS 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function that transforms MPSs into canonical forms 4 | % There is a new function |canonForm.m| under the |Tensor| directory. This function 5 | % uses another new function |Tensor/svdTr.m|, which performs the SVD for tensors 6 | % (not only for matrices) with truncation criteria |Nkeep| and |Skeep|, equivalent 7 | % to the criteria for |canonForm_Ex.m|. 8 | % 9 | % Compare the solution with your implementation of |canonForm_Ex.m|. 10 | %% Solution to Exercise (b): Truncate bond dimensions 11 | 12 | clear 13 | 14 | N = 50; % number of sites 15 | d = 3; % local space dimension 16 | D = 30; % bond dimension 17 | 18 | M = cell(1,N); % MPS; M{n} is the tensor at site n 19 | 20 | for itN = (1:N) 21 | % assign individual tensors 22 | % leg order: left, right, bottom 23 | if itN == 1 24 | % left end; left leg is of size 1 25 | M{itN} = rand(1,D,d); 26 | elseif itN == N 27 | % right end; right leg is of size 1 28 | M{itN} = rand(D,1,d); 29 | else 30 | M{itN} = rand(D,D,d); 31 | end 32 | end 33 | 34 | M = canonForm(M,numel(M),[],0); % left-canonical 35 | M = canonForm(M,0,[],0); % right-canonical 36 | %% 37 | % First, *transform the right-canonical M to the left-canonical form*, for different 38 | % values of the maximum bond dimension |Nkeep|. 39 | 40 | Nkeeps = (5:30).'; % different values of Nkeep. 41 | Ss = zeros(numel(Nkeeps),1); % norm values 42 | 43 | % left-canonical form 44 | for itk = (1:numel(Nkeeps)) 45 | [~,Ss(itk)] = canonForm(M,numel(M),Nkeeps(itk),0); 46 | end 47 | 48 | figure; 49 | plot(Nkeeps,Ss,'LineWidth',1); 50 | set(gca,'LineWidth',1,'FontSize',13,'YScale','log'); 51 | xlabel('Nkeep'); 52 | ylabel('Norm'); 53 | title('Left-canonical form'); 54 | grid on; 55 | %% 56 | % We see that the norm almost does not change. Why? You can keep track of the 57 | % singular values for each iteration of the transformation. By inserting |disp(diag(S).')| 58 | % directly after the SVD inside the for-loop of |canonForm.m|, you will see that 59 | % the largest singular value is almost unity, and the other singular values are 60 | % much smaller than the largest one. Therefore, the truncation of such small singular 61 | % values and their associated singular vectors barely affects the result. 62 | %% 63 | % Then how about to *transform the right-canonical |M| into right-canonical 64 | % form again, with truncating bonds*? 65 | 66 | % right-canonical form 67 | for itk = (1:numel(Nkeeps)) 68 | [~,Ss(itk)] = canonForm(M,0,Nkeeps(itk),0); 69 | end 70 | 71 | figure; 72 | plot(Nkeeps,Ss,'LineWidth',1); 73 | set(gca,'LineWidth',1,'FontSize',13,'YScale','log'); 74 | xlabel('Nkeep'); 75 | ylabel('Norm'); 76 | title('Right-canonical form'); 77 | grid on; 78 | %% 79 | % The norm decreases exponentially, with decreasing |Nkeep|. Why? In the input 80 | % |M|, all the tensors are already right-normalized; that is, they are equivalent 81 | % to unitary matrices. The singular values of the unitary matrices are unity! 82 | % So the truncation of such singular values result in the loss of information. 83 | %% 84 | % Let's consider also the bond-canonical form. The norm also decreases exponentially 85 | % with decreasing |Nkeep|. It is because the right half of the MPS is brought 86 | % *again* into the right-canonical form, with truncating large singular values. 87 | 88 | % bond-canonical form 89 | for itk = (1:numel(Nkeeps)) 90 | [~,Stmp] = canonForm(M,25,Nkeeps(itk),0); 91 | % Stmp is vector, because of bond-canonical form 92 | Ss(itk) = norm(Stmp); 93 | end 94 | 95 | figure; 96 | plot(Nkeeps,Ss,'LineWidth',1); 97 | set(gca,'LineWidth',1,'FontSize',13,'YScale','log'); 98 | xlabel('Nkeep'); 99 | ylabel('Norm'); 100 | title(['Bond-canonical form between M\{', ... 101 | sprintf('%i',25),'\} and M\{', ... 102 | sprintf('%i',26),'\}']); 103 | grid on; -------------------------------------------------------------------------------- /Tutorials/T05.2_CanonicalForm_sol/CanonicalForm_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.2_CanonicalForm_sol/CanonicalForm_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T05.2_CanonicalForm_sol/CanonicalForm_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T05.2_CanonicalForm_sol/CanonicalForm_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T06.1_AKLT/AKLT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T06.1_AKLT/AKLT.pdf -------------------------------------------------------------------------------- /Tutorials/T06.1_AKLT_sol/AKLT_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T06.1_AKLT_sol/AKLT_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T06.2_ExpValues_AKLT/ExpValues_AKLT.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T06.2_ExpValues_AKLT/ExpValues_AKLT.mlx -------------------------------------------------------------------------------- /Tutorials/T06.2_ExpValues_AKLT/ExpValues_AKLT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T06.2_ExpValues_AKLT/ExpValues_AKLT.pdf -------------------------------------------------------------------------------- /Tutorials/T06.2_ExpValues_AKLT_sol/ExpValues_AKLT_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Expectation values in the AKLT state 2 | % Author: 3 | %% Solution to Exercise (a): Magnetization 4 | % First, we create the tensor at each bulk site of the AKLT state. 5 | 6 | clear 7 | 8 | AKLT = zeros(2,2,3); 9 | % local spin S_z = +1 10 | AKLT(1,2,1) = sqrt(2/3); 11 | % local spin S_z = 0 12 | AKLT(1,1,2) = -1/sqrt(3); 13 | AKLT(2,2,2) = +1/sqrt(3); 14 | % local spin S_z = -1 15 | AKLT(2,1,3) = -sqrt(2/3); 16 | %% 17 | % Defain the array |Sz_val| to which the magnetization values will be assigned. 18 | % Its first dimension runs over site indices. Its second and third indices are 19 | % for the boundary conditions $\alpha$ for the leftmost leg and $\beta$ for the 20 | % rightmost leg, respectively. 21 | 22 | L = 50; % number of sites 23 | [S,I] = getLocalSpace('Spin',1); 24 | Sz = S(:,:,2); % spin-z 25 | Sz_val = zeros(L,2,2); 26 | %% 27 | % Now we compute the magnetization. 28 | 29 | for it1 = (1:2) % boundary condition \alpha 30 | for it2 = (1:2) % boundary condition \beta 31 | % the whole MPS 32 | M = cell(1,L); 33 | M(:) = {AKLT}; 34 | M{1} = M{1}(it1,:,:); 35 | M{end} = M{end}(:,it2,:); 36 | M = canonForm(M,L,[],0); % left-canonical form 37 | 38 | for itN = (1:L) % compute magnetization at itN 39 | T = updateLeft([],[],M{itN},Sz,2,M{itN}); 40 | 41 | for itN2 = (itN+1:L) 42 | T = updateLeft(T,2,M{itN2},[],[],M{itN2}); 43 | end 44 | 45 | Sz_val(itN,it1,it2) = T; 46 | end 47 | end 48 | end 49 | %% 50 | % Compare the numerical results and the exact results. 51 | 52 | for it1 = (1:2) 53 | for it2 = (1:2) 54 | Sz_exact = (2*(-1)^it1)* ... 55 | ((-1/3).^(1:L).' - (-1)^(it1+it2)*(-1/3).^(L:-1:1).')./ ... 56 | (1 + (-1)^(it1+it2)*(-1/3)^L); 57 | 58 | figure; 59 | hold on; 60 | plot((1:L),Sz_val(:,it1,it2), ... 61 | 'LineWidth',1,'LineStyle','-'); 62 | plot((1:L),Sz_exact, ... 63 | 'LineWidth',1,'LineStyle','--'); 64 | hold off; 65 | set(gca,'LineWidth',1,'FontSize',13); 66 | xlabel('Site index n'); 67 | title(['$\langle \psi(',sprintf('%i,%i',it1,it2), ... 68 | ')|\hat{S}_{[n]z} | \psi(',sprintf('%i,%i',it1,it2), ... 69 | ') \rangle$'], ... 70 | 'Interpreter','latex'); 71 | legend({'Numeric','Exact'},'Location','northeastoutside'); 72 | grid on; 73 | end 74 | end 75 | %% 76 | % Here we see that the magnetization at site 1 is positive (negative) if $\alpha 77 | % = 1 (2)$, and similarly for the magnetization at site $L$. It is because $\alpha 78 | % = \beta = 1$ indicates $S_z = 1/2$ in the bond space and $\alpha = \beta = 2$ 79 | % indicates $S_z = -1/2$. 80 | %% Solution to Exercise (b): Spin-spin correlation 81 | % Compute the spin-spin correlation. The only difference from the above case 82 | % is that another spin-z operator is contracted with the physical (local space) 83 | % legs of the bra and ket tensors at the next site. 84 | 85 | SzSz_val = zeros(L-1,2,2); 86 | % 1st dimension: site indices within (1:(L-1)) 87 | % 2nd dimension: boundary condition for the leftmost leg 88 | % 3rd dimension: boundary condition for the rightmost leg 89 | 90 | for it1 = (1:2) % boundary condition \alpha 91 | for it2 = (1:2) % boundary condition \beta 92 | % the whole MPS 93 | M = cell(1,L); 94 | M(:) = {AKLT}; 95 | M{1} = M{1}(it1,:,:); 96 | M{end} = M{end}(:,it2,:); 97 | M = canonForm(M,L,[],0); % left-canonical form 98 | 99 | for itN = (1:L-1) % compute magnetization at itN 100 | T = updateLeft([],[],M{itN},Sz,2,M{itN}); 101 | 102 | % only difference! 103 | T = updateLeft(T,2,M{itN+1},Sz,2,M{itN+1}); 104 | 105 | for itN2 = (itN+2:L) 106 | T = updateLeft(T,2,M{itN2},[],[],M{itN2}); 107 | end 108 | 109 | SzSz_val(itN,it1,it2) = T; 110 | end 111 | end 112 | end 113 | %% 114 | % Compare the numerical results and the exact results. Note that the exact result 115 | % does not depend on the site index $n$. 116 | 117 | for it1 = (1:2) 118 | for it2 = (1:2) 119 | SzSz_exact = zeros(L-1,1) + ... 120 | ((-4/9) - 4*(-1)^(it1+it2)*(-1/3)^L)/ ... 121 | (1 + (-1)^(it1+it2)*(-1/3)^L); 122 | 123 | figure; 124 | hold on; 125 | plot((1:L-1),SzSz_val(:,it1,it2), ... 126 | 'LineWidth',1,'LineStyle','-'); 127 | plot((1:L-1),SzSz_exact, ... 128 | 'LineWidth',1,'LineStyle','--'); 129 | hold off; 130 | set(gca,'LineWidth',1,'FontSize',13); 131 | xlabel('Site index n'); 132 | title(['$\langle \psi(',sprintf('%i,%i',it1,it2), ... 133 | ')|\hat{S}_{[n]z} \hat{S}_{[n+1]z}| \psi(', ... 134 | sprintf('%i,%i',it1,it2), ... 135 | ') \rangle$'], ... 136 | 'Interpreter','latex'); 137 | legend({'Numeric','Exact'},'Location','northeastoutside'); 138 | grid on; 139 | end 140 | end -------------------------------------------------------------------------------- /Tutorials/T06.2_ExpValues_AKLT_sol/ExpValues_AKLT_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T06.2_ExpValues_AKLT_sol/ExpValues_AKLT_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T06.2_ExpValues_AKLT_sol/ExpValues_AKLT_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T06.2_ExpValues_AKLT_sol/ExpValues_AKLT_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T07.1_MPO_MPS/MPO_MPS.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T07.1_MPO_MPS/MPO_MPS.mlx -------------------------------------------------------------------------------- /Tutorials/T07.1_MPO_MPS/MPO_MPS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T07.1_MPO_MPS/MPO_MPS.pdf -------------------------------------------------------------------------------- /Tutorials/T07.1_MPO_MPS_sol/MPO_MPS_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T07.1_MPO_MPS_sol/MPO_MPS_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T07.1_MPO_MPS_sol/MPO_MPS_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T07.1_MPO_MPS_sol/MPO_MPS_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T08.1_DMRG_GroundState_1site/DMRG_GroundState_1site.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T08.1_DMRG_GroundState_1site/DMRG_GroundState_1site.mlx -------------------------------------------------------------------------------- /Tutorials/T08.1_DMRG_GroundState_1site/DMRG_GroundState_1site.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T08.1_DMRG_GroundState_1site/DMRG_GroundState_1site.pdf -------------------------------------------------------------------------------- /Tutorials/T08.1_DMRG_GroundState_1site_sol/DMRG_GroundState_1site_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] DMRG: Single-site update for ground state search 2 | % Author: 3 | %% Solution to Exercise (a): Initialize MPS with the iterative diagonalization result 4 | % First, we repeat the part in which parameters and operators are defined. 5 | 6 | clear 7 | 8 | % system parameter 9 | J = -1; % coupling strength 10 | L = 40; % number of sites in a chain 11 | 12 | % DMRG parameter 13 | Nkeep = 30; % bond dimension 14 | Nsweep = 4; % number of pairs of left+right sweeps 15 | 16 | % Local operators 17 | [S,I] = getLocalSpace('Spin',1/2); 18 | 19 | % % MPO formulation of Hamiltonian 20 | % Hamiltonian tensor for each chain site 21 | Hloc = cell(4,4); 22 | Hloc(:) = {zeros(size(I))}; 23 | Hloc{1,1} = I; 24 | Hloc{2,1} = S(:,:,1); 25 | Hloc{3,1} = S(:,:,3); 26 | Hloc{4,2} = J*S(:,:,1)'; 27 | Hloc{4,3} = J*S(:,:,3)'; 28 | Hloc{end,end} = I; 29 | Hloc = cell2mat(reshape(Hloc,[1 1 size(Hloc,1) size(Hloc,2)])); 30 | 31 | % full chain 32 | Hs = cell(1,L); 33 | Hs(:) = {Hloc}; 34 | Hs{1} = Hs{1}(:,:,end,:); % choose the last components of the left leg 35 | Hs{end} = Hs{end}(:,:,:,1); % choose the first components of the right leg 36 | %% 37 | % Now we perform iterative diagonalization with the MPO Hamiltonian. At each 38 | % iteration, the Hamiltonian is obtained by contracting the MPO tensors with the 39 | % MPS tensors (bras and kets). The contraction result is rank-3, having a leg 40 | % pointing right. This leg accounts for the interaction terms involving operators 41 | % at later sites, not included in the Hilbert space up to the current iteration. 42 | % To obtain the Hamiltonian that only involves the sites included so far, we project 43 | % the right leg onto its first index. By doing this, the Hamiltonian becomes rank-2 44 | % (as the projected leg becomes a dummy leg with singleton dimension) and can 45 | % be diagonalized. 46 | 47 | Minit = cell(1,L); 48 | 49 | % tensors for the vaccum (i.e., dummy leg) 50 | Hprev = 1; % initialize Hamiltonian with 1, as we will use MPO 51 | Aprev = 1; % identity tensor for the dummy leg 52 | 53 | for itN = (1:L) 54 | % add new site 55 | Anow = getIdentity(Aprev,2,I,2,[1 3 2]); 56 | Hnow = updateLeft(Hprev,3,Anow,Hs{itN},4,Anow); 57 | 58 | Hmat = Hnow(:,:,1); 59 | [V,D] = eig((Hmat+Hmat')/2); 60 | [D,ids] = sort(diag(D),'ascend'); 61 | if itN < L 62 | Ntr = min([numel(D);Nkeep]); 63 | else 64 | Ntr = 1; 65 | end 66 | V = V(:,ids(1:Ntr)); 67 | 68 | Anow = contract(Anow,3,2,V,2,1,[1 3 2]); 69 | 70 | Minit{itN} = Anow; 71 | 72 | Hprev = contract(Hnow,3,2,V,2,1); 73 | Hprev = contract(V',2,2,Hprev,3,1,[1 3 2]); 74 | Aprev = Anow; 75 | end 76 | %% 77 | % |M| represents the MPS for the ground state out of the iterative diagonalization. 78 | %% Solution to Exercise (b): Complete the single-site DMRG function 79 | % Check out the funciton |DMRG_GS_1site.m| under the |DMRG| sub-directory. Compare 80 | % with your implementation of |DMRG_GS_1site_Ex.m|! 81 | 82 | [M0,E0,Eiter] = DMRG_GS_1site(Minit,Hs,Nkeep,Nsweep); 83 | E0_exact = 0.5 - (1/2/sin(pi/2/(L+1))); % exact value 84 | disptime(['Exact GS energy = ',sprintf('%.5g',E0_exact),', DMRG = ', ... 85 | sprintf('%.5g',E0),', error = ',sprintf('%.5g',E0-E0_exact)]); -------------------------------------------------------------------------------- /Tutorials/T08.1_DMRG_GroundState_1site_sol/DMRG_GroundState_1site_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T08.1_DMRG_GroundState_1site_sol/DMRG_GroundState_1site_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T08.1_DMRG_GroundState_1site_sol/DMRG_GroundState_1site_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T08.1_DMRG_GroundState_1site_sol/DMRG_GroundState_1site_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T09.1_DMRG_ExcitedState_1site/DMRG_ExcitedState_1site.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.1_DMRG_ExcitedState_1site/DMRG_ExcitedState_1site.mlx -------------------------------------------------------------------------------- /Tutorials/T09.1_DMRG_ExcitedState_1site/DMRG_ExcitedState_1site.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.1_DMRG_ExcitedState_1site/DMRG_ExcitedState_1site.pdf -------------------------------------------------------------------------------- /Tutorials/T09.1_DMRG_ExcitedState_1site_sol/DMRG_ExcitedState_1site_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] DMRG: Single-site update for excited state search 2 | % Author: 3 | %% Solution to Exercise (a): Complete the single-site DMRG for first excited state search 4 | % Check out the funciton |DMRG_1ES_1site.m| under the |DMRG| sub-directory. 5 | % Compare with your implementation of |DMRG_1ES_1site_Ex.m|! -------------------------------------------------------------------------------- /Tutorials/T09.1_DMRG_ExcitedState_1site_sol/DMRG_ExcitedState_1site_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.1_DMRG_ExcitedState_1site_sol/DMRG_ExcitedState_1site_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T09.1_DMRG_ExcitedState_1site_sol/DMRG_ExcitedState_1site_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.1_DMRG_ExcitedState_1site_sol/DMRG_ExcitedState_1site_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T09.2_DMRG_GroundState_2site/DMRG_GroundState_2site.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.2_DMRG_GroundState_2site/DMRG_GroundState_2site.mlx -------------------------------------------------------------------------------- /Tutorials/T09.2_DMRG_GroundState_2site/DMRG_GroundState_2site.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.2_DMRG_GroundState_2site/DMRG_GroundState_2site.pdf -------------------------------------------------------------------------------- /Tutorials/T09.2_DMRG_GroundState_2site_sol/DMRG_GroundState_2site_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] DMRG: Two-site update for ground state search 2 | % Author: 3 | %% Solution to Exercise (a): Complete the two-site DMRG function 4 | % Check out the funciton |DMRG_GS_2site.m| under the |DMRG| sub-directory. Compare 5 | % with your implementation of |DMRG_GS_2site_Ex.m|! 6 | %% Solution to Exercise (b): Majumdar-Ghosh model 7 | % We first construct the MPO Hamiltonian for the Majumdar-Ghosh model, 8 | % 9 | % $$\hat{H} = \sum_{\ell=1}^{L-1} \hat{\vec{S}}_\ell \cdot \hat{\vec{S}}_{\ell+1} 10 | % + \frac{1}{2} \sum_{\ell=1}^{L-2} \hat{\vec{S}}_\ell \cdot \hat{\vec{S}}_{\ell+2} 11 | % .$$ 12 | 13 | clear 14 | 15 | % system parameter 16 | J1 = 1; % nearest-neighbour coupling strength 17 | J2 = 1/2; % next-nearest-neighbour coupling strength 18 | L = 40; % number of sites in a chain 19 | 20 | % DMRG parameter 21 | Nkeep = 30; % bond dimension 22 | Nsweep = 5; % number of pairs of left+right sweeps 23 | 24 | % Local operators 25 | [S,I] = getLocalSpace('Spin',1/2); 26 | 27 | % Hamiltonian tensor for each chain site 28 | Hloc = cell(8,8); 29 | Hloc(:) = {zeros(size(I))}; 30 | Hloc{1,1} = I; 31 | Hloc{2,1} = S(:,:,1); 32 | Hloc{3,1} = S(:,:,2); 33 | Hloc{4,1} = S(:,:,3); 34 | Hloc{5,2} = I; 35 | Hloc{6,3} = I; 36 | Hloc{7,4} = I; 37 | Hloc{8,2} = J1*(Hloc{2,1}'); 38 | Hloc{8,3} = J1*(Hloc{3,1}'); 39 | Hloc{8,4} = J1*(Hloc{4,1}'); 40 | Hloc{8,5} = J2*(Hloc{2,1}'); 41 | Hloc{8,6} = J2*(Hloc{3,1}'); 42 | Hloc{8,7} = J2*(Hloc{4,1}'); 43 | Hloc{end,end} = I; 44 | Hloc = cell2mat(reshape(Hloc,[1 1 size(Hloc,1) size(Hloc,2)])); 45 | 46 | % full chain 47 | Hs = cell(1,L); 48 | Hs(:) = {Hloc}; 49 | Hs{1} = Hs{1}(:,:,end,:); % choose the last components of the left leg 50 | Hs{end} = Hs{end}(:,:,:,1); % choose the first components of the right leg 51 | %% 52 | % We define a random MPS as the initial guess. The iterative diagonalization 53 | % result can be used as well. 54 | 55 | Minit = cell(1,L); 56 | Minit{1} = rand(1,Nkeep,size(I,2)); 57 | Minit{end} = rand(Nkeep,1,size(I,2)); 58 | for itN = (2:L-1) 59 | Minit{itN} = rand(Nkeep,Nkeep,size(I,2)); 60 | end 61 | [M0,E0,Eiter,Sv] = DMRG_GS_2site(Minit,Hs,Nkeep,Nsweep); 62 | E0_exact = -3*L/8; % exact value 63 | disptime(['Exact GS energy = ',sprintf('%.5g',E0_exact),', DMRG = ', ... 64 | sprintf('%.5g',E0),', error = ',sprintf('%.5g',E0-E0_exact)]); 65 | figure; 66 | plot((1:numel(Eiter))/L,Eiter(:)-E0_exact,'LineWidth',1); 67 | set(gca,'XScale','Linear','YScale','log','FontSize',13,'LineWidth',1); 68 | xlim([0 2*Nsweep]); 69 | grid on; 70 | xlabel('# of sweeps'); 71 | ylabel('Ground-state energy error'); 72 | %% 73 | % The error is of the order of double precision. 74 | %% 75 | % Let's look at the sizes of the MPS tensors. 76 | 77 | M0 78 | %% 79 | % The bond dimensions are oscillating between 1 and 2! 80 | % 81 | % To see what happened, we first plot the singular values on different bonds. 82 | % Since |Sv{1}| and |Sv{end}| just contain the norm of the MPS, we plot the data 83 | % for |Sv(2:end-1)|. 84 | 85 | % maximum bond dimension 86 | nSv_max = max(cellfun('prodofsize',Sv(2:end-1))) 87 | Sv_tot = nan(nSv_max,numel(Sv(2:end-1))); 88 | for itN = (1:size(Sv_tot,2)) 89 | Sv_tot(1:numel(Sv{itN+1}),itN) = Sv{itN+1}; 90 | end 91 | figure; 92 | hold on; 93 | plot((1:numel(Sv)-2),Sv_tot(1,:).','x','LineWidth',1,'MarkerSize',10); 94 | plot((1:numel(Sv)-2),Sv_tot(2,:).','+','LineWidth',1,'MarkerSize',10); 95 | hold off; 96 | set(gca,'XScale','Linear','YScale','log','FontSize',13,'LineWidth',1); 97 | grid on; 98 | xlabel('bond index') 99 | ylabel('singular values') 100 | %% 101 | % The singular values oscillates, with periodicity 2. On the bond between sites 102 | % n and n+1 with odd n, the singular values are doubly degenerate, i.e., $(1/\sqrt{2}, 103 | % 1/\sqrt{2})$: 104 | 105 | Sv{2}*sqrt(2) 106 | %% 107 | % Meanwhile, on the bond between sites n and n+1 with even n, there is only 108 | % one singular value which is unity: 109 | 110 | Sv{3} 111 | %% 112 | % The singleton bond dimension indicates a direct product. That is, the ground 113 | % state of the Majumdar-Ghosh model is just the direct product of $L/2$ copies 114 | % of spin singlets. It can be also seen from the spin-spin correlation function 115 | % $\langle \Psi_0 | \hat{S}_{\ell,+} \hat{S}_{\ell+1,-} | \Psi_0 \rangle$. 116 | 117 | % compute correlation function for the nearest-neighbour spins 118 | SS = zeros(1,L-1); 119 | for itN = (2:L) 120 | T = updateLeft([],[],M0{itN-1},S(:,:,1)*sqrt(2),3,M0{itN-1}); 121 | T = updateLeft(T,3,M0{itN},S(:,:,3)*sqrt(2),3,M0{itN}); 122 | 123 | for itN2 = ((itN+1):L) 124 | T = updateLeft(T,2,M0{itN2},[],[],M0{itN2}); 125 | end 126 | 127 | SS(itN-1) = T; 128 | end 129 | 130 | figure; 131 | plot((1:L-1),SS,'LineWidth',1); 132 | set(gca,'FontSize',13,'LineWidth',1); 133 | xlabel('$\ell$','Interpreter','latex'); 134 | ylabel('$\langle \hat{S}^+_\ell \hat{S}^-_{\ell+1} \rangle$', ... 135 | 'Interpreter','latex'); 136 | xlim([1 L-1]); 137 | grid on; -------------------------------------------------------------------------------- /Tutorials/T09.2_DMRG_GroundState_2site_sol/DMRG_GroundState_2site_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.2_DMRG_GroundState_2site_sol/DMRG_GroundState_2site_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T09.2_DMRG_GroundState_2site_sol/DMRG_GroundState_2site_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T09.2_DMRG_GroundState_2site_sol/DMRG_GroundState_2site_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T10.1_iTEBD_GroundState/iTEBD_GroundState.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T10.1_iTEBD_GroundState/iTEBD_GroundState.mlx -------------------------------------------------------------------------------- /Tutorials/T10.1_iTEBD_GroundState/iTEBD_GroundState.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T10.1_iTEBD_GroundState/iTEBD_GroundState.pdf -------------------------------------------------------------------------------- /Tutorials/T10.1_iTEBD_GroundState_sol/iTEBD_GroundState_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T10.1_iTEBD_GroundState_sol/iTEBD_GroundState_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T10.1_iTEBD_GroundState_sol/iTEBD_GroundState_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T10.1_iTEBD_GroundState_sol/iTEBD_GroundState_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T11.1_iTEBD_Hastings_Ortho/iTEBD_Hastings_Ortho.m: -------------------------------------------------------------------------------- 1 | %% iTEBD: Hastings' method, orthonormalization 2 | % Author: 3 | %% 4 | % In this tutorial, we will practice two approaches that overcome the limitations 5 | % of Vidal's original formulation of the iTEBD method. 6 | %% 7 | % # The first is Hastings' version of iTEBD, proposed in [], which avoids the division 9 | % by small singular values. It will be implemented as Exercise (a). 10 | % # The second is the orthonormalization of an inifinite MPS in the $\Gamma$-$\Lambda$ 11 | % notation, developed by []. It will be implemented 13 | % as Exercise (b) and used to obtain the scaling behavior of a spin-spin correlation 14 | % function in Exercise (c). 15 | %% Exercise (a): Complete the function for Hastings' version of iTEBD 16 | % There is a function |iTEBD_GS_Hastings_Ex.m|, which is in the same sub-directory 17 | % with this script. It is incomplete. Complete the parts enclosed by the comments 18 | % |TODO (start)| and |TODO (end)|. 19 | %% 20 | % You can check your implementation of |iTEBD_GS_Hastings_Ex.m| by running the 21 | % calculation of the spin-1 Heisenberg model on the infinite spin chain. Here 22 | % we only modify the names of tensors, from |Gamma| to |As|. 23 | 24 | clear 25 | 26 | % iTEBD parameters 27 | Nkeep = 30; 28 | tau_ini = 1; % initial imaginary time step size 29 | tau_fin = 1e-6; % final imaginary time step size 30 | Nstep = 2e3; % number of imaginary time steps 31 | taus = tau_ini*((tau_fin/tau_ini).^linspace(0,1,Nstep)); 32 | % discrete imaginary time steps; decays slowly but exponentially 33 | 34 | % Local operators 35 | [S,I] = getLocalSpace('Spin',1); 36 | 37 | % Heisenberg interaction as two-site gate S*S' 38 | H = contract(S,3,3,permute(conj(S),[2 1 3]),3,3); 39 | 40 | % Initialize with random Lambda and Gamma 41 | Lambda = cell(1,2); 42 | Bs = cell(1,2); 43 | for itn = (1:numel(Lambda)) 44 | Lambda{itn} = rand(Nkeep,1); 45 | Bs{itn} = rand(Nkeep,Nkeep,size(I,2)); 46 | end 47 | 48 | % iTEBD ground state search 49 | [Lambda,Bs,Eiter] = iTEBD_GS_Hastings_Ex(Lambda,Bs,H,Nkeep,taus); 50 | Eexact = -1.401484039; 51 | % reshape Eiter for convenient plot 52 | Eiter2 = reshape(permute(Eiter,[2 1 3]), ... 53 | [size(Eiter,2)*size(Eiter,1) size(Eiter,3)]); 54 | figure; 55 | plot((1:size(Eiter2,1)).'/2,Eiter2-Eexact,'LineWidth',1); 56 | set(gca,'LineWidth',1,'FontSize',13,'YScale','linear'); 57 | xlim([0 30]); 58 | xlabel('# of imaginary-time evolution steps'); 59 | ylabel('Energy per bond - exact energy'); 60 | legend({'Even','Odd'}); 61 | grid on; 62 | figure; 63 | plot((1:size(Eiter2,1)).'/2,mean(Eiter2,2)-Eexact,'LineWidth',1); 64 | set(gca,'YScale','log','LineWidth',1,'FontSize',13); 65 | xlabel('Step'); 66 | ylabel('Energy per bond - exact energy'); 67 | legend({'Even-odd averaged'}); 68 | grid on; 69 | %% Exercise (b): Complete the function for the orthonormalization 70 | % There is a function |ortho_Orus_Ex.m|, which is in the same sub-directory 71 | % with this script. It is incomplete. Complete the parts enclosed by the comments 72 | % |TODO (start)| and |TODO (end)|. 73 | %% Exercise (c): Correlation length of the spin-1 Heisenberg model 74 | % In this Exercise, we will investigate a spin-spin correlation function $\langle 75 | % \hat{S}_{\ell,z} \hat{S}_{\ell+n,z} \rangle$ for the spin-1 Heisenberg model 76 | % on the infinite spin chain. The scaling behavior of the correlation function 77 | % for large distance $n$ can be identified by analyzing transfer operators, as 78 | % we discussed in the lecture on translationally invariant MPS. The transfer operators, 79 | % however, need to be constructed from the orthonormalized tensors, since the 80 | % scaling analysis rely on the left- or right-normalization of the tensors. Therefore, 81 | % here we obtain the orthonormalized tensors by applying |ortho_Orus_Ex.m| to 82 | % the result from Vidal's iTEBD. (You can also use Hastings' version as well, 83 | % but the current implementation of |ortho_Orus_Ex.m| is based on the $\Gamma$-$\Lambda$ 84 | % notation, not on the left- or right-normalized tensors used by Hastings' version.) 85 | % 86 | % (i) Show that, for even and large $n \gg 1$, the correlation decays exponentially, 87 | % $\langle \hat{S}_{\ell,z} \hat{S}_{\ell+n,z} \rangle \sim \exp ( - n /\xi)$, 88 | % by constructing and analyzing transfer operators for the two-site unit cell. 89 | % 90 | % (ii) Analyze how the correlation length $\xi$ changes with different |Nkeep|'s. 91 | % (_Hint_: Indeed, $\xi$ depends on the maximum bond dimension $N_\mathrm{keep}$ 92 | % (|Nkeep|). In the limit of $N_\mathrm{keep} \to \infty$, it will converge to 93 | % $\xi \simeq 6$, as found in []). -------------------------------------------------------------------------------- /Tutorials/T11.1_iTEBD_Hastings_Ortho/iTEBD_Hastings_Ortho.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T11.1_iTEBD_Hastings_Ortho/iTEBD_Hastings_Ortho.mlx -------------------------------------------------------------------------------- /Tutorials/T11.1_iTEBD_Hastings_Ortho/iTEBD_Hastings_Ortho.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T11.1_iTEBD_Hastings_Ortho/iTEBD_Hastings_Ortho.pdf -------------------------------------------------------------------------------- /Tutorials/T11.1_iTEBD_Hastings_Ortho/ortho_Orus_Ex.m: -------------------------------------------------------------------------------- 1 | function [Lambda,Gamma] = ortho_Orus_Ex (Lambda,Gamma) 2 | % < Description > 3 | % 4 | % [Lambda,Gamma] = ortho_Orus_Ex (Lambda,Gamma) 5 | % 6 | % Orthonormalize an infinite MPS in Vidal's Gamma-Lambda representation, 7 | % by using the method given in Orus2008 [R. Orus & G. Vidal, Phys. Rev. B 8 | % 78, 155117 (2008)]. After the orthonormalization, the rank-3 tensors 9 | % Lambda*Gamma and Gamma*Lambda become left- and right-normalized, 10 | % respectively. 11 | % 12 | % < Input > 13 | % Lambda : [vector] A column vector contanining the singular values. 14 | % Gamma : [rank-3 tensor] Its first and second legs contract to the same 15 | % Lambda, given as the first input to this function. 16 | % When the unit cell contains n sites with n > 1, there will be 17 | % multiple Gamma and Lambda, say Gammas{1}, ..., Gammas{n}, and 18 | % Lambdas{1}, ..., Lambdas{n}. Here Lambdas{k} sits between Gammas{k} 19 | % and Gammas{k+1}. To orthonormalize the tensors in such a case, we 20 | % first contract the tensors ("coarse-graining" called in Orus2008) 21 | % to make a single Gamma tensor as the second input to this function: 22 | % Gammas{1}*Lambdas{1}*Gammas{2}* ... *Gammas{n-1}*Lambdas{n-1}*Gammas{n} 23 | % And Lambdas{n} becomes the first input to this function. 24 | % 25 | % < Output > 26 | % Lambda : [vector] A column vector contanining the singular values, after 27 | % the orthonormalization. 28 | % Gamma : [rank-3 tensor] Rank-3 Gamma tensor after the orthonormalization. 29 | % If the unit cell is larger than one site, we contract the outputs 30 | % as Lambda*Gamma*Lambda, and sequentially SVD it to obtain 31 | % individual Gamma's and Lambda's for individual sites. 32 | % 33 | % Written by S.Lee (Jun.16,2017) 34 | % Rewritten by S.Lee (Oct.03,2022): Revised for the Tensor Networks course 35 | % at SNU. 36 | 37 | % sanity check of input 38 | if ~isvector(Lambda) 39 | error('ERR: ''Lambda'' should be a vector.'); 40 | elseif any(numel(Lambda) ~= [size(Gamma,1) size(Gamma,2)]) 41 | error('ERR: The dimensions of the 1st and 2nd legs of ''Gamma'' should be equal to the length of ''Lambda''.'); 42 | end 43 | 44 | % % % % TODO (start) % % % % 45 | 46 | % do SVD in Fig. 2(ii) of Orus2008 47 | 48 | % contraction in Fig. 2(ii) of Orus2008 49 | 50 | % % % % TODO (end) % % % % 51 | 52 | end 53 | 54 | 55 | 56 | function X = ortho_Orus_vec (M,isright) 57 | % < Description > 58 | % 59 | % X = ortho_Orus_vec (M,isright) 60 | % 61 | % This function obtains the eigenvector V with the eigenvalue of the 62 | % largest absolute value (called "dominant eigenvector" in Orus2008), for a 63 | % transfer operator made of a ket tensor M. And it decomposes V = X*X', 64 | % where V is brought into a matrix form of size D-by-D, where D is the bond 65 | % dimension for the left and right legs of M. 66 | % Here we follow the recipe described in Sec. II and Fig. 2 of Orus2008, 67 | % except that we simply use the MATLAB "eigs" function to get the dominant 68 | % eigenvector. 69 | % 70 | % < Input > 71 | % M : [rank-3 tensor] A ket tensor, to be used to construct a transfer 72 | % operator. Its legs are ordered as left-right-bottom(physical). 73 | % isright : [logical] If true, this function finds the right eigenvector. 74 | % If false, it finds the left eigenvector. 75 | % 76 | % < Output > 77 | % X : [matrix] The dominant eigenvector, brought in its matrix form, is 78 | % decomposed as X * X'. 79 | % 80 | % Written by S.Lee (Jun.16,2017) 81 | % Rewritten by S.Lee (Oct.03,2022): Revised for the Tensor Networks course 82 | % at SNU. 83 | 84 | D = size(M,1); 85 | 86 | % transfer operator 87 | T = contract(conj(M),3,3,M,3,3,[3 1 4 2]); 88 | 89 | % Convert T into a matrix form 90 | T = reshape(T,D^2*[1 1]); 91 | 92 | if ~isright 93 | T = T'; % Hermitian conjugate 94 | end 95 | 96 | % % % % TODO (start) % % % % 97 | 98 | % Get the dominant eigenvector by using "eigs" 99 | 100 | % Convert the dominant eigenvector into a matrix form, and diagonalize the 101 | % matrix 102 | % Note: The dominant eigenvector is equivalent up to overall sign; 103 | % therefore, multiply -1 if the trace of the eigenvector in the matrix form 104 | % is negative 105 | 106 | % Once the overall sign is fixed, then the eigenvalues (for the dominant 107 | % eigenvector in the matrix form) should be non-negative; negative values 108 | % are numerical errors. Remove the negative eigenvalues and the 109 | % corresponding eigenvectors. 110 | 111 | % % % % TODO (end) % % % % 112 | 113 | end 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /Tutorials/T11.1_iTEBD_Hastings_Ortho_sol/iTEBD_Hastings_Ortho_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T11.1_iTEBD_Hastings_Ortho_sol/iTEBD_Hastings_Ortho_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T11.1_iTEBD_Hastings_Ortho_sol/iTEBD_Hastings_Ortho_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T11.1_iTEBD_Hastings_Ortho_sol/iTEBD_Hastings_Ortho_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T12.1_tDMRG_ErrorAnalysis/tDMRG_ErrorAnalysis.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.1_tDMRG_ErrorAnalysis/tDMRG_ErrorAnalysis.mlx -------------------------------------------------------------------------------- /Tutorials/T12.1_tDMRG_ErrorAnalysis/tDMRG_ErrorAnalysis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.1_tDMRG_ErrorAnalysis/tDMRG_ErrorAnalysis.pdf -------------------------------------------------------------------------------- /Tutorials/T12.1_tDMRG_ErrorAnalysis_sol/tDMRG_ErrorAnalysis_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.1_tDMRG_ErrorAnalysis_sol/tDMRG_ErrorAnalysis_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T12.1_tDMRG_ErrorAnalysis_sol/tDMRG_ErrorAnalysis_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.1_tDMRG_ErrorAnalysis_sol/tDMRG_ErrorAnalysis_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T12.2_MPO_TimeEvolution/MPO_TimeEvolution.m: -------------------------------------------------------------------------------- 1 | %% MPO representation of time evolution operators 2 | % Author: 3 | %% 4 | % In the tutorial for tDMRG, we have time-evolved MPSs by applying rows of two-site 5 | % gates. Often, it is useful to represent a time evolution operator for a time 6 | % step as an MPO. 7 | % 8 | % In this tutorial, we use two different approaches for constructing MPOs that 9 | % represent time evolution operators. As a concrete example, we consider the XY 10 | % spin-1/2 chain of even length $L$, 11 | % 12 | % $$\hat{H}_{\mathrm{XY}}= -\sum_{\ell=1}^{L-1} (\hat{S}_{\ell,x} \hat{S}_{\ell+1,x} 13 | % + \hat{S}_{\ell,y} \hat{S}_{\ell+1,y})= -\frac{1}{2} \sum_{\ell=1}^{L-1} (\hat{S}_{\ell,+} 14 | % \hat{S}_{\ell+1,-} + \hat{S}_{\ell,-} \hat{S}_{\ell+1,+}) ,$$ 15 | % 16 | % and a time step $\Delta t = 0.01$. 17 | %% Exercise (a): MPO for the first-order Trotterization 18 | % In the first-order Trotter decomposition, the time evolution operator for 19 | % time step $\Delta t$ is split into $\exp (-\mathrm{i} \hat{H}_\mathrm{odd} \Delta 20 | % t) \exp (-\mathrm{i} \hat{H}_\mathrm{even} \Delta t)$, which has an error of 21 | % the order of $O(\Delta t^2)$. The decomposition is represented by two rows of 22 | % time evolution gates, as depicted in the upper part of the figure below: 23 | % 24 | % 25 | % 26 | % We can decompose each two-site gate into two single-site tensors at different 27 | % sites, and contract the single-site tensors from different rows, to obtain an 28 | % MPO shown in the lower part of the figure above. Write a script that constructs 29 | % such an MPO for general even $L$. Verify your result by explicitly computing 30 | % $\exp (-\mathrm{i} \hat{H}_\mathrm{odd} \Delta t) \exp (-\mathrm{i} \hat{H}_\mathrm{even} 31 | % \Delta t)$ for a small system, say $L = 6$. 32 | %% Exercise (b): MPO for the first-order Taylor expansion 33 | % On the other hand, we can make another first-order approximation of $\exp(-\mathrm{i} 34 | % \hat{H}_\mathrm{XY} \Delta t)$, which as an error of the order of $O(\Delta 35 | % t^2)$, by using the Taylor expansion: namely, $\exp(-\mathrm{i} \hat{H}_\mathrm{XY} 36 | % \Delta t) \approx \hat{I} - \mathrm{i} \hat{H}_\mathrm{XY} \Delta t$. Write 37 | % a script that constructs such an MPO for general even $L$. Verify your result 38 | % by explicitly computing $\hat{I} - \mathrm{i} \hat{H}_\mathrm{XY} \Delta t$ 39 | % for a small system, say $L = 6$. 40 | % 41 | % (_Hint_: Refer to Sec. 5.2 of Schollwoeck2011 [].) -------------------------------------------------------------------------------- /Tutorials/T12.2_MPO_TimeEvolution/MPO_TimeEvolution.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.2_MPO_TimeEvolution/MPO_TimeEvolution.mlx -------------------------------------------------------------------------------- /Tutorials/T12.2_MPO_TimeEvolution/MPO_TimeEvolution.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.2_MPO_TimeEvolution/MPO_TimeEvolution.pdf -------------------------------------------------------------------------------- /Tutorials/T12.2_MPO_TimeEvolution_sol/MPO_TimeEvolution_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.2_MPO_TimeEvolution_sol/MPO_TimeEvolution_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T12.2_MPO_TimeEvolution_sol/MPO_TimeEvolution_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T12.2_MPO_TimeEvolution_sol/MPO_TimeEvolution_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT/FiniteT.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T13.1_FiniteT/FiniteT.mlx -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT/FiniteT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T13.1_FiniteT/FiniteT.pdf -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT/XTRG_Ex.m: -------------------------------------------------------------------------------- 1 | function [taus,lnZs,rho] = XTRG_Ex (Hs,dt,tmax,Nkeep,Nsweep) 2 | % < Description > 3 | % 4 | % [taus,lnZs,rho] = XTRG_Ex (Hs,dt,tmax,Nkeep,Nsweep) 5 | % 6 | % Exponential tensor renormalization group (XTRG) method for simulating 7 | % thermal density matrix as a matrix product operator (MPO). This function 8 | % takes logarithmic imaginary-time steps and evaluates the logarithm of the 9 | % partition function at those time instances. 10 | % 11 | % < Input > 12 | % Hs : [1 x N cell array] MPO representation of the Hamiltonian. Each Hs{n} 13 | % is a rank-4 tensor acting on site n. The order of legs of Hs{n} is 14 | % bottom-top-left-right, where the bottom (top) leg contracts to the 15 | % physical leg of bra (ket) tensor. 16 | % dt : [numeric] Initial value of the imaginary time. In this function, the 17 | % first thermal density matrix in its MPO form is constructied via 18 | % linearization, i.e., I - dt*H, where I is the identity for the 19 | % whole Hilbert space and H is the Hamiltonian. 20 | % tmax : [numeric] Maximum time to be reached at the end of iterations. 21 | % "tmax" equals to the target inverse temperature. 22 | % Nkeep : [integer] Maximum bond dimension of the MPO form of the purified 23 | % thermal state. 24 | % Nsweep : [integer] Number of round trips in the variational MPO 25 | % multiplication. "Nkeep" and "Nsweep" are directly forwarded to 26 | % "DMRG/mtimes_MPO.m"; see the description of those inputs therein. 27 | % 28 | % < Output > 29 | % taus : [numeric] Time instances taken by logarithmically within the XTRG. 30 | % The actual imaginary time instances are -1i*taus. The elements of 31 | % "taus" equal to the inverse temperature values. 32 | % lnZs : [numeric] Logarithms of the partition function measured at time 33 | % instances "taus". 34 | % rho : [cell] The MPO representation of the thermal density matrix at the 35 | % last time instance. 36 | % 37 | % Written by S.Lee (Oct.10,2022) 38 | 39 | tobj = tic2; 40 | 41 | N = numel(Hs); 42 | 43 | % % % % TODO (start) % % % % 44 | % initialize the first thermal density matrix, given by linearizing the 45 | % exponential, I - dt*H, where H is the MPO Hamiltonian 46 | rho = cell(1,N); 47 | rho{1} = cat(4,getIdentity(Hs{1},2),-dt*Hs{1}); 48 | for itN = (2:N-1) 49 | 50 | end 51 | % % % % TODO (end) % % % % 52 | 53 | Nstep = round(log2(tmax)-log2(dt)); 54 | taus = dt*(2.^(1:Nstep)); 55 | lnZs = zeros(size(taus)); % result 56 | 57 | % show information 58 | fprintf('Finite T: XTRG\n'); 59 | fprintf(['N = ',sprintf('%i',N),', Nkeep = ',sprintf('%i',Nkeep), ... 60 | ', Nsweep = ',sprintf('%i',Nsweep), ... 61 | ', dt = ',sprintf('%.4g',dt),', tmax = ',sprintf('%.4g',taus(end)), ... 62 | ' (',sprintf('%.4g',Nstep),' steps)\n']); 63 | 64 | % main part of XTRG; iterative "squaring" of density matrix 65 | for it1 = (1:Nstep) 66 | % Hermitian conjugate 67 | rho2 = rho; 68 | for itN = (1:N) 69 | rho2{itN} = permute(conj(rho2{itN}),[2 1 3 4]); 70 | end 71 | 72 | % MPO multiplication 73 | rho = mtimes_MPO_Ex(rho2,rho,Nkeep,Nsweep); 74 | 75 | % % % % TODO (start) % % % % 76 | % compute the trace, which leads to the partition function 77 | 78 | 79 | % add the log of the trace to the result array lnZs 80 | 81 | 82 | % add the result from the last iteration, since the MPO gets normalized 83 | % at every iteration (see below) to avoid divergence 84 | 85 | 86 | % normalize the MPO 87 | 88 | 89 | % % % % TODO (end) % % % % 90 | 91 | if (mod(it1,round(Nstep/10)) == 0) || (it1 == Nstep) 92 | disptime(['#',sprintf('%i/%i',[it1,Nstep]), ... 93 | ' : t = ',sprintf('%.4g/%.4g',[taus(it1),taus(end)])]); 94 | end 95 | end 96 | 97 | toc2(tobj,'-v'); 98 | chkmem; 99 | 100 | end 101 | -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT/mtimes_MPO_Ex.m: -------------------------------------------------------------------------------- 1 | function C = mtimes_MPO_Ex (B,A,Nkeep,Nsweep) 2 | % < Description > 3 | % 4 | % C = mtimes_MPO_Ex (B,A,Nkeep,Nsweep) 5 | % 6 | % Variational multiplication of two matrix product operators (MPOs) B and 7 | % A, where A multiplies to B from above (i.e., A is the top row, and B is 8 | % the row below A). In the variational scheme, the multiplication result C 9 | % is initialized as A, and then undergoes a two-site update, as described 10 | % in App. D 1 of [B.-B. Chen et al., Phys. Rev. X 8, 031082 (2018)]. 11 | % 12 | % < Input > 13 | % B, A : [1 x L cell array] MPOs to be multiplied together. Each tensor 14 | % A{n} or B{n} is a rank-4 tensor acting on site n. Its legs are 15 | % ordered as bottom-top-left-right, where the bottom (top) leg 16 | % contracts to the physical leg of bra (ket) tensor. 17 | % Nkeep : [numeric] The maximum bond dimension for the result MPO C. 18 | % Nsweep : [numeric] Number of round trips of sweeping. There will be 19 | % Nsweep pairs of left-to-right sweep and right-to-left sweep. That 20 | % is, the first sweep is left-to-right and the last is right-to-left. 21 | % 22 | % < Output > 23 | % C : [1 x L cell array] Multiplication of A and B. Each tensor C{n} 24 | % follows the same leg order convention as thoes in A and B. 25 | % 26 | % Written by S.Lee (Oct.10,2022) 27 | 28 | N = numel(A); 29 | 30 | % sanity check 31 | if N ~= numel(B) 32 | error('ERR: Length of two input MPOs do not match.'); 33 | end 34 | for itN = (1:N) 35 | if (itN == 1) && ~all([size(A{itN},3),size(B{itN},3)] == 1) 36 | error('ERR: The leftmost leg of an MPO should be dummy.'); 37 | elseif (itN == N) && ~all([size(A{itN},4),size(B{itN},4)] == 1) 38 | error('ERR: The rightmost leg of an MPO should be dummy.'); 39 | elseif (itN < N) && (size(A{itN},4) ~= size(A{itN+1},3)) 40 | error(['ERR: The fourth (= right) leg of A{',sprintf('%i',itN), ... 41 | '} and the third (= left) leg of A{',sprintf('%i',itN+1), ... 42 | '} do not have the same dimensions.']); 43 | elseif (itN < N) && (size(B{itN},4) ~= size(B{itN+1},3)) 44 | error(['ERR: The fourth (= right) leg of B{',sprintf('%i',itN), ... 45 | '} and the third (= left) leg of B{',sprintf('%i',itN+1), ... 46 | '} do not have the same dimensions.']); 47 | elseif size(A{itN},1) ~= size(B{itN},2) 48 | error(['ERR: The first (= bottom) leg of A{',sprintf('%i',itN), ... 49 | '} and the second (= top) leg of B{',sprintf('%i',itN), ... 50 | '} do not have the same dimensions.']); 51 | end 52 | end 53 | % % % 54 | 55 | % Initialize C with A 56 | C = A; 57 | 58 | % Bring C into right-canonical form 59 | % First, convert rank-4 tensors into rank-3, by merging physical legs, to 60 | % use the canonForm function that canonicalize MPSs 61 | Aloc = cell(1,N); % isometries for merging the bottom and top legs of MPO tensors 62 | for itN = (1:N) 63 | Aloc{itN} = getIdentity(C{itN},1,C{itN},2); 64 | C{itN} = contract(C{itN},4,[1 2],Aloc{itN},3,[1 2]); 65 | end 66 | % Use canonForm for MPS 67 | C = canonForm(C,0,Nkeep,[]); 68 | % Bring back to rank-4 69 | for itN = (1:N) 70 | C{itN} = contract(C{itN},3,3,conj(Aloc{itN}),3,3,[3 4 1 2]); 71 | end 72 | 73 | % Contractions of A, B, and C^\dagger. They correspond to the "effective 74 | % Hamitonian" for the left and right parts in the ground and excited states 75 | % search within the DMRG. As in the DMRG, we set ABC{1} and ABC{N+2} as 76 | % 1's, to simplify the code. 77 | ABC = cell(1,N+2); 78 | ABC{1} = 1; 79 | ABC{end} = 1; 80 | % % % % TODO (start) % % % % 81 | % Feel free to define sub-functions for tensor contractions that appear 82 | % multiple times in the code. By doing so, you will be able to write a 83 | % simpler code with less probability of encountering bugs! 84 | 85 | % contract from right, since the first sweep is left-to-right 86 | for itN = (N:-1:1) 87 | ABC{itN+1} = 88 | end 89 | 90 | for itS = (1:Nsweep) 91 | for itN = (1:(N-2)) % left-to-right sweep 92 | 93 | end 94 | 95 | for itN = ((N-1):-1:1) % right-to-left sweep 96 | 97 | end 98 | end 99 | % % % % TODO (end) % % % % 100 | 101 | end 102 | -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT_sol/FiniteT_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solutions] Finite temperatures: Purification and XTRG 2 | % Author: 3 | %% Solution to Exercises (a)-(c): Complete the functions 4 | % There are complete functions, |mtimes_MPO.m|, |finT_puri.m|, and |XTRG.m|, 5 | % all under the |DMRG| sub-directory. Compare with your version! -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT_sol/FiniteT_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T13.1_FiniteT_sol/FiniteT_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T13.1_FiniteT_sol/FiniteT_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T13.1_FiniteT_sol/FiniteT_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T14.1_NRG_Eflow/NRG_Eflow.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.1_NRG_Eflow/NRG_Eflow.mlx -------------------------------------------------------------------------------- /Tutorials/T14.1_NRG_Eflow/NRG_Eflow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.1_NRG_Eflow/NRG_Eflow.pdf -------------------------------------------------------------------------------- /Tutorials/T14.1_NRG_Eflow_sol/NRG_Eflow_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.1_NRG_Eflow_sol/NRG_Eflow_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T14.1_NRG_Eflow_sol/NRG_Eflow_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.1_NRG_Eflow_sol/NRG_Eflow_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T14.2_NRG_ImpThermodyn/NRG_ImpThermodyn.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.2_NRG_ImpThermodyn/NRG_ImpThermodyn.mlx -------------------------------------------------------------------------------- /Tutorials/T14.2_NRG_ImpThermodyn/NRG_ImpThermodyn.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.2_NRG_ImpThermodyn/NRG_ImpThermodyn.pdf -------------------------------------------------------------------------------- /Tutorials/T14.2_NRG_ImpThermodyn_sol/NRG_ImpThermodyn_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solutions] NRG: Impurity contribution to thermodynamic properties 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for computing thermodynamic properties 4 | % The complete version of the function, |getTDconv.m|, is added under the |NRG| 5 | % sub-directory. Compare with your version! 6 | %% Solution to Exercise (b): Single-impurity Kondo model 7 | % Perform the iterative diagonalization for the whole Kondo model (SIKM). For 8 | % details of the iterative diagonalization for the SIKM, refer to the solution 9 | % of the last tutorial. 10 | 11 | clear 12 | 13 | % Hamiltonian parameters 14 | U = 4e-3; % Coulomb interaction at the impurity 15 | epsd = -U/2; % impurity on-site energy 16 | Delta0 = 2.5e-4; % hybridization strength 17 | D = 1; % half-bandwidth 18 | J = 8*Delta0/pi/U; % Kondo coupling strength 19 | ozin = [-1;1]*D; 20 | RhoV2in = [1;1]; 21 | 22 | % NRG parameters 23 | Lambda = 2.5; % discretization parameter 24 | N = 55; % length of the Wilson chain 25 | Nkeep = 300; 26 | 27 | % Wilson chain 28 | N2 = 30; 29 | [ff,~] = doCLD(ozin,RhoV2in,Lambda,N2); 30 | % post-processing 31 | ff = [ff;ff(end).*(Lambda.^(-(1:(N-numel(ff))).'/2))]; 32 | gg = zeros(size(ff)); 33 | 34 | % Construct local operators 35 | [F,Z,S,I] = getLocalSpace('FermionS'); 36 | [Ss,Is] = getLocalSpace('Spin',1/2); 37 | 38 | % particle number operator 39 | NF = cat(3,contract(conj(F(:,:,1)),3,[1 3],F(:,:,1),3,[1 3]), ... 40 | contract(conj(F(:,:,2)),3,[1 3],F(:,:,2),3,[1 3])); 41 | 42 | % ket tensor 43 | A0 = getIdentity(Is,2,I,2,[1 3 2]); 44 | 45 | % Impurity Hamiltonian 46 | H0 = updateLeft(Ss,3,A0,permute(conj(S),[2 1 3]),3,A0); 47 | % take the Hermitian conjugate to S 48 | H0 = H0*(2*J); 49 | H0 = H0 + gg(1)*updateLeft([],[],A0,sum(NF,3),2,A0); 50 | 51 | % iterative diagonalization 52 | Inrg = NRG_IterDiag (H0,A0,Lambda,ff(2:end),F,gg(2:end),sum(NF,3),Z,Nkeep); 53 | beta0 = 1; % parameter to define temperature values 54 | [T,Tchi,Sent] = getTDconv(Inrg,S(:,:,2),beta0,Ss(:,:,2)); 55 | %% 56 | % Perform the iterative diagonalization for the bath only. We replace the Kondo 57 | % impurity with vacuum. 58 | 59 | A0_2 = getIdentity(1,2,I,2); % numeric 1 for vaccum 60 | H0_2 = gg(1)*updateLeft([],[],A0_2,sum(NF,3),2,A0_2); 61 | Inrg2 = NRG_IterDiag (H0_2,A0_2,Lambda,ff(2:end),F,gg(2:end),sum(NF,3),Z,Nkeep); 62 | [~,Tchi2,Sent2] = getTDconv(Inrg2,S(:,:,2),beta0); 63 | %% 64 | % Then subtract the thermodynamic properties from the bath only from those from 65 | % the whole impurity model, to obtain the impurity contribution. 66 | 67 | % impurity contribution to the spin susceptibility (* temperature) 68 | Tchi_imp = Tchi - Tchi2; 69 | % impurity contribution to the entropy 70 | Sent_imp = Sent - Sent2; 71 | 72 | logT = log(T); 73 | % impurity contribution to the specific heat C = T* dS/dT = dS / d(log T) 74 | C_imp = interp1((logT(1:end-1)+logT(2:end))/2, ... 75 | diff(Sent_imp)./diff(logT),logT,'linear','extrap'); 76 | 77 | % Sommerfeld-Wilson ratio 78 | WR = (Tchi_imp./C_imp)*(4*(pi^2)/3); 79 | %% 80 | % To rescale the temperature, we compute the Kondo temperature $T_\mathrm{K}$. 81 | % Here we use the formula from the second-order poor man's scaling calculation. 82 | 83 | % Kondo temperature 84 | TK = sqrt(J) * exp(-1/J); % half-bandwidth D = 1 85 | disp(TK); 86 | %% 87 | % Plot the result. 88 | 89 | figure; 90 | semilogx(T/TK,(Tchi_imp./T)*(4*TK), ... 91 | T/TK,Sent_imp/log(2), ... 92 | T/TK,WR,'LineWidth',1); 93 | set(gca,'LineWidth',1,'FontSize',13); 94 | xlabel('$T / T_\mathrm{K}$','Interpreter','latex'); 95 | legend({'$4 T_\mathrm{K} \chi_\mathrm{imp}$'; ... 96 | '$S_\mathrm{imp} / \ln 2$'; ... 97 | '$R$'}, ... 98 | 'Interpreter','latex','Location','northwest'); 99 | ylim([0 3]); 100 | xlim([min(T) max(T)]/TK); 101 | grid on; 102 | %% 103 | % The curves of $R(T)$ and $\chi_\mathrm{imp}(T)$ for the SIKM exhibit similar 104 | % behavior as those for the SIAM. Compare this plot with the demonstration plot. 105 | % The kinks of $R$ at the highest and the lowest temperatures come from numerical 106 | % artifact. 107 | % 108 | % On the other hand, the curve of $S_\mathrm{imp}(T)$ for the SIKM shows different 109 | % features from that for the SIAM. $S_\mathrm{imp} (T)$ for the SIAM has had three 110 | % plateaus that represent three regimes: (i) $\ln 4$ for the free orbital regime, 111 | % (ii) $\ln 2$ for the local moment regime, and (iii) $0$ for the strong coupling 112 | % regime. $S_\mathrm{imp} (T)$ for the SIKM has only two plateaus: (i) $\ln 2$ 113 | % for the local moment regime and (ii) $0$ for the strong coupling regime. 114 | % 115 | % The absence of the free orbital regime is natural. In the derivation of the 116 | % SIKM out of the SIAM, the doubly-occupied and the empty states of the impurity 117 | % are "integrated out." As the result, the impurity of the SIKM has only spin 118 | % degrees of freedom. That is, there is no free orbital regime at all for the 119 | % SIKM. -------------------------------------------------------------------------------- /Tutorials/T14.2_NRG_ImpThermodyn_sol/NRG_ImpThermodyn_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.2_NRG_ImpThermodyn_sol/NRG_ImpThermodyn_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T14.2_NRG_ImpThermodyn_sol/NRG_ImpThermodyn_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T14.2_NRG_ImpThermodyn_sol/NRG_ImpThermodyn_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T15.1_NRG_FullDensityMatrix/NRG_FullDensityMatrix.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T15.1_NRG_FullDensityMatrix/NRG_FullDensityMatrix.mlx -------------------------------------------------------------------------------- /Tutorials/T15.1_NRG_FullDensityMatrix/NRG_FullDensityMatrix.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T15.1_NRG_FullDensityMatrix/NRG_FullDensityMatrix.pdf -------------------------------------------------------------------------------- /Tutorials/T15.1_NRG_FullDensityMatrix/getRhoFDM_Ex.m: -------------------------------------------------------------------------------- 1 | function Inrg = getRhoFDM_Ex (Inrg,T) 2 | % < Description > 3 | % 4 | % Inrg = getRhoFDM_Ex (Inrg,T) 5 | % 6 | % Construct the full density matrix (FDM) in the basis of both discarded 7 | % and kept states, for given temperature T. 8 | % 9 | % < Input > 10 | % Inrg : [struct] NRG information obtained after running NRG_IterDiag. 11 | % T : [number] Temperature. Here we set \hbar = k_B = 1. 12 | % 13 | % < Ouput > 14 | % Inrg : [struct] NRG result. It keeps the result of NRG_IterDiag. In 15 | % addition to the result, this function adds two more fields to Inrg: 16 | % .RD, .RK : [cell] Full density matrix in the discarded and kept state 17 | % basis, respectively. Each cell element Inrg.RD{n} is a column 18 | % vector whose elements are the density matrix elements associated 19 | % with the discarded energy eigenstates at iteration n-1. (Refer to 20 | % the documentation of NRG_IterDiag for the interation indexing 21 | % convention.) 22 | % Inrg.RK{n} is a matrix in the basis of the kept energy eigenstates 23 | % at the iteration n-1. 24 | % 25 | % Written by S.Lee (May 22,2017) 26 | % Updated by S.Lee (May 12,2019): Revised for SoSe 2019. 27 | % Updated by S.Lee (Jun.20,2020): Revised for SoSe 2020. 28 | % Updated by S.Lee (Oct.22,2020): Revised for the 2022 Fall semester at SNU. 29 | 30 | tobj = tic2; 31 | disptime(['Construct full density matrix @ T = ',sprintf('%.4g',T),'.']); 32 | 33 | N = numel(Inrg.E0); 34 | 35 | % extract the local space dimension from ket tensors 36 | locdim = zeros(N,1); 37 | for itN = (1:N) 38 | if ~isempty(Inrg.AK{itN}) 39 | locdim(itN) = size(Inrg.AK{itN},3); 40 | else 41 | locdim(itN) = size(Inrg.AD{itN},3); 42 | end 43 | end 44 | 45 | RD = cell(1,N); % FDM in the discarded state basis; row vector 46 | RK = cell(1,N); % FDM in the kept state basis; matrix 47 | Ztot = zeros(1,N); % sum of Boltzmann weights 48 | 49 | % % % % TODO (start) % % % % 50 | % the shift of energy in each shell measured from the lowest-energy of the 51 | % last iteration 52 | 53 | % obtain the Boltzamann weights 54 | for itN = (1:N) 55 | % Obtain the column vector RD{itN} whose elements are the Boltzmann 56 | % weights 57 | RD{itN} = 58 | Ztot(itN) = sum(RD{itN}); 59 | end 60 | 61 | Ztot = sum(Ztot); 62 | 63 | % normalize the Boltzmann weights to get the elements of the density matrix 64 | % in the discarded basis 65 | for itN = (1:N) 66 | RD{itN} = RD{itN}/Ztot; 67 | end 68 | 69 | % update the FDM in the kept basis 70 | for itN = (N:-1:2) 71 | % Construct RK{itN-1} as the sum of RD{itN} and RK{itN}, with the local 72 | % Hilbert space for the site s(itN-1). 73 | 74 | % NOTE: AK and AD are in left-canonical form, not right-canonical. 75 | 76 | end 77 | % % % % TODO (end) % % % % 78 | 79 | if sum(RD{end}) > 1e-2 80 | disptime('WRN: sum(Inrg.RD{end}) > 1e-2 ; chain length may not be long enough.'); 81 | end 82 | 83 | Inrg.T = T; % record T in Inrg 84 | Inrg.Ztot = Ztot; % record the sum of Boltzmann weights 85 | Inrg.RK = RK; 86 | Inrg.RD = RD; 87 | 88 | toc2(tobj,'-v'); 89 | 90 | end -------------------------------------------------------------------------------- /Tutorials/T15.1_NRG_FullDensityMatrix_sol/NRG_FullDensityMatrix_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] NRG: Full density matrix 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for constructing the full density matrix 4 | % The completed function, |getRhoFDM.m|, is added under the |NRG| directory. 5 | % Compare with your version! -------------------------------------------------------------------------------- /Tutorials/T15.1_NRG_FullDensityMatrix_sol/NRG_FullDensityMatrix_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T15.1_NRG_FullDensityMatrix_sol/NRG_FullDensityMatrix_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T15.1_NRG_FullDensityMatrix_sol/NRG_FullDensityMatrix_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T15.1_NRG_FullDensityMatrix_sol/NRG_FullDensityMatrix_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T16.1_NRG_SpectralFunc/NRG_SpectralFunc.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T16.1_NRG_SpectralFunc/NRG_SpectralFunc.mlx -------------------------------------------------------------------------------- /Tutorials/T16.1_NRG_SpectralFunc/NRG_SpectralFunc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T16.1_NRG_SpectralFunc/NRG_SpectralFunc.pdf -------------------------------------------------------------------------------- /Tutorials/T16.1_NRG_SpectralFunc/getAdisc_Ex.m: -------------------------------------------------------------------------------- 1 | function [odisc,Adisc] = getAdisc_Ex (Inrg,O1,O2,Z,varargin) 2 | % < Description > 3 | % 4 | % [odisc,Adisc] = getAdisc_Ex (Inrg,O1,O2,Z [, option]); % for fermionic operators O1 & O2 5 | % [odisc,Adisc] = getAdisc_Ex (Inrg,O1,O2,[],[, option]); % for bosonic operators O1 & O2 6 | % 7 | % Obtain the discrete spectral function of the correlation function, by 8 | % evaluating its Lehmann representation via the full density matrix NRG 9 | % (fdmNRG). The correlation function is defined by a pair of operators O1 10 | % and O2, 11 | % 12 | % G = -1i*\theta(t) Tr [ \rho * [O1(t), O2']_{+-} ], 13 | % 14 | % where \theta(t) means the theta function, Tr means the trace, and O1(t) 15 | % is a time evolution of O1 in the Heisenberg picture. The commutator takes 16 | % + (-) if O1 and O2 are fermionic (bosonic). Note that O2 is Hermitian- 17 | % conjugated in the definition of the correlator we use. 18 | % 19 | % In this fdmNRG routine, we assume that both O1 and O2 act on the third (= 20 | % bottom) leg of A0 (the isometry for the impurity site, also an input to 21 | % NRG_IterDiag). The resulting delta functions from the Lehmann 22 | % representation are binned into a histogram vector Adisc. 23 | % 24 | % < Input > 25 | % Inrg : [struct] NRG information obtained after running NRG_IterDiag and 26 | % then running getRhoFDM. 27 | % O1, O2 : [tensor] Operator acting at the impurity, corresponding to the 28 | % third (= bottom) leg of A0. 29 | % Z : [tensor] Fermionic sign operator at each chain site. If O1 and O2 are 30 | % bosonic, then put Z as empty []. 31 | % 32 | % < Option > 33 | % 'emin', .. : [number] Minimum (in absolute value) frequency limit. 34 | % (Default: 1e-12) 35 | % 'emax', .. : [number] Minimum (in absolute value) frequency limit. 36 | % (Default: 1e4) 37 | % 'estep', .. : [number] Number of bins per decade, i.e., number of bins 38 | % from frequency 1 to 10. 39 | % (Default: 500) 40 | % 41 | % < Output > 42 | % odisc : [vector] Logarithmic grid of frequency. 43 | % Adisc : [vector] Discrete spectral weights corresponding to odisc. 44 | % Adisc(n) is the sum of the spectral weights whose frequency 45 | % positions are close to the bin center position odisc(n). 46 | % 47 | % Written by S.Lee (May 22,2017) 48 | % Updated by S.Lee (May 11,2019): Revised for SoSe 2019. 49 | % Updated by S.Lee (Jun.20,2020): Revised for SoSe 2020. 50 | % Updated by S.Lee (Oct.25,2020): Revised for the 2022 Fall semester at SNU. 51 | 52 | tobj = tic2; 53 | 54 | % default option values 55 | emin = 1e-12; 56 | emax = 1e4; 57 | estep = 500; 58 | 59 | % % parsing option 60 | while ~isempty(varargin) 61 | switch varargin{1} 62 | case 'emin' 63 | emin = varargin{2}; 64 | varargin(1:2) = []; 65 | case 'emax' 66 | emax = varargin{2}; 67 | varargin(1:2) = []; 68 | case 'estep' 69 | estep = varargin{2}; 70 | varargin(1:2) = []; 71 | otherwise 72 | error('ERR: Unknown option.'); 73 | end 74 | end 75 | % % % 76 | 77 | % sanity check 78 | if ~all([size(Inrg.AK{1},1),size(Inrg.AD{1},1)] == 1) 79 | error('ERR: The first (= left) leg of the first isometries (for the impurity site) should have singleton dimensions.') 80 | end 81 | if ~isempty(Z) 82 | disptime('Correlation function for anti-commuting operators.'); 83 | opsign = 1; % anti-commutation 84 | else 85 | disptime('Correlation function for commuting operators'); 86 | opsign = -1; % commutation 87 | end 88 | 89 | loge = (floor(log10(emin)*estep):ceil(log10(emax)*estep)).'/estep; 90 | odisc = 10.^(loge); 91 | odisc = [-flipud(odisc);0;odisc]; % bin centers; zero frequency in the middle 92 | Adisc = zeros(size(odisc)); % to be binned 93 | 94 | 95 | % % % % TODO (start) % % % % 96 | 97 | 98 | for itN = (1:N) 99 | 100 | 101 | disptime(['#',sprintf('%02i/%02i',[itN-1, N-1]),' : sum(Adisc) = ', ... 102 | sprintf('%.4g',sum(Adisc(:)))]); % show accumulative sum of the discrete weights 103 | end 104 | % % % % TODO (end) % % % % 105 | 106 | toc2(tobj,'-v'); 107 | chkmem; 108 | 109 | end -------------------------------------------------------------------------------- /Tutorials/T16.1_NRG_SpectralFunc_sol/NRG_SpectralFunc_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T16.1_NRG_SpectralFunc_sol/NRG_SpectralFunc_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T16.1_NRG_SpectralFunc_sol/NRG_SpectralFunc_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T16.1_NRG_SpectralFunc_sol/NRG_SpectralFunc_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T16.2_Lehmann_NonInt/Lehmann_NonInt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T16.2_Lehmann_NonInt/Lehmann_NonInt.pdf -------------------------------------------------------------------------------- /Tutorials/T16.2_Lehmann_NonInt/Lehmann_NonInt.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt,a4paper,oneside]{article} 2 | 3 | \usepackage{amsmath,amssymb,amsthm} 4 | \usepackage{graphicx} 5 | \usepackage{enumerate} 6 | %\usepackage{enumitem} 7 | \usepackage{lastpage} % total page number 8 | \usepackage[bottom]{footmisc} % to keep footnotes at the bottom of pages 9 | \usepackage{braket} 10 | 11 | \usepackage{fancyhdr} 12 | \pagestyle{fancyplain} 13 | %\pagestyle{fancy} 14 | %\setlength{\headheight}{13.6pt} 15 | %\setlength{\headsep}{7pt} 16 | %\voffset-4.4mm 17 | \renewcommand{\headrulewidth}{0.4pt} 18 | \renewcommand{\footrulewidth}{0.4pt} 19 | 20 | \voffset-4.4mm 21 | \hoffset-4.4mm 22 | \marginparsep0mm 23 | \marginparwidth0mm 24 | \oddsidemargin0mm 25 | \evensidemargin0mm 26 | \topmargin 0mm 27 | \textwidth 168mm 28 | \textheight 240mm %A4: 297mm x 210mm 29 | \setlength{\footskip}{25pt} 30 | \setlength{\headsep}{13pt} %default 25pt 31 | \setlength{\headheight}{12pt} %def 3 | % 4 | % yr = KKi2r_Ex (xi, yi [,option]) 5 | % 6 | % Convert the imaginary part of a causal function into the real part, by 7 | % using the Kramers-Kronig relation. If the input is the real part, then 8 | % yi = -KKi2r(xr,yr) yields the imaginary part. 9 | % This function computes the Cauchy principal value (also called principal 10 | % value integral) 11 | % yr (xr) = (1/pi) * P. \int_{-\infty}^{\infty} dx yi(x) / (x-xr) , 12 | % where P. means the principal value and yi(x), yr(xr) are the functions 13 | % corresponding to the discrete data (xi, yi), (xi, yr), respectively. The 14 | % integration is done numerically, assuming that the input function is the 15 | % linear interpolation among the points (xi, yi) on the interval [xi(1), 16 | % xi(end)], and have 1/x tails on (-\infty, xi(1)) and (xi(end), \infty) 17 | % extrapolated from (xi(1), yi(1) and (xi(end), yi(end)), respectively. 18 | % 19 | % < Input > 20 | % xi : [vector] Grid points of x values on which the imaginary part(s) of 21 | % the causal function(s) are defined. 22 | % yi : [vector, matrix, or multi-dimensional array] The imaginary part(s) 23 | % of the causal function(s) on the grid given by "xi". Each column of 24 | % "yi" corresponds to a function, representing the imaginary part 25 | % of a function as a piecewise linear function connecting the (x,y) 26 | % pairs specified xi and the column elements. numel(xi) == size(yi,1) 27 | % should hold. 28 | % 29 | % < Output > 30 | % yr : [vector, matrix, or multi-dimensional array] The real part(s) of the 31 | % causal function(s) on the grid specifed by xi. It has the same 32 | % structure as the input "yi"; each column of "yr" corresponds to the 33 | % column of yi with the same column index. 34 | % 35 | % Rewritten by S.Lee (Oct.28,2022): Revised for the TN lecture course at 36 | % SNU. 37 | 38 | % % % sanity check 39 | if isvector(xi) 40 | xi = xi(:); 41 | else 42 | error('ERR: input frequency ''xi'' is not a vector.'); 43 | end 44 | if isvector(yi) 45 | yi = yi(:); 46 | end 47 | if numel(xi) ~= size(yi,1) 48 | error('ERR: numel(xi) ~= size(yi,1)'); 49 | end 50 | 51 | sz = size(yi); % save the size for future reshaping 52 | yi = yi(:,:); % make yi to matrix; reshape later 53 | 54 | if any(diff(xi) < 0) 55 | disptime('WRN: input ''xi'' is not in ascending order.'); 56 | [xi,ids] = sort(xi,'ascend'); 57 | yi = yi(ids,:); 58 | end 59 | if any(diff(xi) == 0) 60 | error('ERR: Input ''xi'' is not unique.'); 61 | end 62 | % % % % 63 | 64 | dxi = diff(xi); 65 | a = (yi(2:end,:) - yi(1:end-1,:))./dxi; % piecewise slope 66 | b = (-xi(1:end-1).*yi(2:end,:)+xi(2:end).*yi(1:end-1,:))./dxi; % piecewise y intercept 67 | 68 | ids = find(xi ~= 0); % to be used for adding the tail contributions 69 | 70 | yr = zeros(size(yi)); % result array 71 | 72 | % % % % TODO (start) % % % % 73 | 74 | % perform the numerical integration, assuming that the input function is the 75 | % linear interpolation among the points (xi, yi) on the interval [xi(1), 76 | % xi(end)], and have 1/x tails on (-\infty, xi(1)) and (xi(end), \infty) 77 | % extrapolated from (xi(1), yi(1) and (xi(end), yi(end)), respectively. 78 | 79 | % % % % TODO (end) % % % % 80 | 81 | if ~isequal(size(yr),sz) 82 | yr = reshape(yr,sz); 83 | end 84 | 85 | % catch e 86 | % disp2(getReport(e)) 87 | % disp2('Let''s Debug!'); 88 | % keyboard; 89 | % end 90 | 91 | end -------------------------------------------------------------------------------- /Tutorials/T17.1_NRG_SelfEnergy/NRG_SelfEnergy.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.1_NRG_SelfEnergy/NRG_SelfEnergy.mlx -------------------------------------------------------------------------------- /Tutorials/T17.1_NRG_SelfEnergy/NRG_SelfEnergy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.1_NRG_SelfEnergy/NRG_SelfEnergy.pdf -------------------------------------------------------------------------------- /Tutorials/T17.1_NRG_SelfEnergy/SEtrick_Ex.m: -------------------------------------------------------------------------------- 1 | function [SE,varargout] = SEtrick_Ex (ocont,Acont1,Acont2,varargin) 2 | % < Description > 3 | % 4 | % SE = SEtrick_Ex (ocont,Acont1,Acont2) % self-energy only 5 | % [SE,Aimp] = SEtrick_Ex (ocont,Acont1,Acont2,epsd,RhoV2in) % also obtain 6 | % % the improved estimate of the impurity spectral function 7 | % 8 | % Compute the impurity self-energy due to interactions and (if "epsd" and 9 | % "RhoV2in" are given) the improved estimate of the impurity spectral 10 | % function by using Bulla's "self-energy trick", developed in [R. Bulla, A. 11 | % C. Hewson, and Th. Pruschke, J. Phys. Condens. Matter 10, 8365 (1998)]. 12 | % Based on the equation of motion (EoM) for the impurity Green's function 13 | % G[F, F'] that is derived by differentiating the function with respect to 14 | % the first time argument for the first operator F, the self-energy SE can 15 | % be given by the ratio of two correlation functions, 16 | % SE = G[FH, F'] / G[F, F'], ----- (1) 17 | % where F is the particle annihilation operator at the impurity, F' is the 18 | % Hermitian conjugate of F, FH = [F, HU] is the commutator, and HU means 19 | % the interaction (i.e., non-quadratic) term of the impurity Hamiltonian. 20 | % 21 | % < Input > 22 | % ocont : [numeric vector] Frequency grid on which "Acont1" and "Acont2" 23 | % (also "RhoV2in", if given) are defined. 24 | % Acont1 : [numeric] The spectral function part of a correlator G[F, F']. 25 | % This 'Acont1' is the broadned curve (by using 'getAcont') from the 26 | % discrete spectral data of the spectral function of G[F,F'] (by 27 | % running 'getAdisc'). 28 | % Acont2 : [numeric] The spectral function part of a correlator G[FH, F']. 29 | % It is obtained in a similar way as "Acont1", while using FH instead 30 | % of F. 31 | % epsd : (Optional) [numeric] Impurity level. 32 | % RhoV2in : (Optional) [numeric] The spectral function part of the 33 | % hybridization function defined on the frequency grid "ocont". 34 | % 35 | % < Output > 36 | % The data structure (in terms of dimensions) of the following results are 37 | % the same as the input Acont1. 38 | % SE : [numeric] Impurity self-energy. 39 | % Aimp : (Optional) [numeric] Improved impurity spectral function, obtained 40 | % by susbstituting the self-energy "SE" and the optional input 41 | % "RhoV2in" into the Dyson equation. 42 | % 43 | % Written by S.Lee (Oct.28,2022): for the TN lecture course at SNU. 44 | 45 | % default values of numerical parameter and optional inputs 46 | iSEmax = -1e-14; % maximum of the imaginary part of the self-energy, needed 47 | % to post-process the self-energy; see below 48 | epsd = []; 49 | RhoV2in = []; 50 | 51 | % parse optional input 52 | if ~isempty(varargin) 53 | if numel(varargin) < 2 54 | error('ERR: If optional inputs are given, there should be two optional inputs.'); 55 | end 56 | epsd = varargin{1}; 57 | RhoV2in = varargin{2}; 58 | end 59 | 60 | % sanity check 61 | if ~isvector(ocont) 62 | error('ERR: ''ocont'' should be a vector.'); 63 | elseif ~ismatrix(Acont1) || ~ismatrix(Acont2) 64 | error('ERR: ''Acont1'' and ''Acont2'' should be matrices.'); 65 | elseif ~all(numel(ocont) == [size(Acont1,1) size(Acont2,1)]) 66 | error('ERR: size(Acont1,1) and size(Acont2,1) should be equal to numel(ocont).'); 67 | elseif size(Acont1,2) ~= size(Acont2,2) 68 | error('ERR: size(Acont1,2) and size(Acont2,2) should be the same.'); 69 | elseif isempty(RhoV2in) ~= isempty(epsd) 70 | error('ERR: Only one optional input was set?'); 71 | elseif ~isempty(RhoV2in) 72 | if ~ismatrix(RhoV2in) 73 | error('ERR: RhoV2in should be a matrix.'); 74 | elseif numel(ocont) ~= size(RhoV2in,1) 75 | error('ERR: size(RhoV2in,1) should be equal to numel(ocont).'); 76 | elseif size(epsd,1) ~= 1 77 | error('ERR: ''epsd'' should be a row vector.'); 78 | elseif ~all(size(Acont1,2) == [size(epsd,2) size(RhoV2in,2)]) 79 | error('ERR: size(epsd,2) and size(RhoV2in,2) should be equal to size(Acont1,2).'); 80 | end 81 | end 82 | % % % % 83 | 84 | % % % % TODO (start) % % % % 85 | 86 | 87 | % The imaginary part of the self-energy should be negative, to ensure the 88 | % causality. However, in this numerical calculation, the imaginary part can 89 | % be slightly positive over a narrow interval. To make the numerical result 90 | % of SE physically sound, we cut off the imaginary part larger than 91 | % "iSEmax" (defined above) to be bounded by "iSEmax". 92 | 93 | if ~isempty(RhoV2in) % compute the improved estimate of the impurity spectral function 94 | 95 | 96 | varargout = {... % put the variable for the improved estimate here 97 | }; 98 | end 99 | 100 | % % % % TODO (end) % % % % 101 | 102 | end -------------------------------------------------------------------------------- /Tutorials/T17.1_NRG_SelfEnergy_sol/NRG_SelfEnergy_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solutions] NRG: Bulla's self-energy trick 2 | % Author: 3 | %% Solutions to Exercise (a): Complete the function for the Kramers–Kronig (KK) relation and Exercise (b): Complete the function for Bulla's self-energy trick 4 | % The completed functions for the KK relation and the self-energy trick are 5 | % uploaded as, respectively, |Util/KKi2r.m| and |NRG/SEtrick.m|. Compare with 6 | % your version! -------------------------------------------------------------------------------- /Tutorials/T17.1_NRG_SelfEnergy_sol/NRG_SelfEnergy_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.1_NRG_SelfEnergy_sol/NRG_SelfEnergy_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T17.1_NRG_SelfEnergy_sol/NRG_SelfEnergy_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.1_NRG_SelfEnergy_sol/NRG_SelfEnergy_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T17.2_DMFT_NRG/DMFT_Hubbard_Ex.m: -------------------------------------------------------------------------------- 1 | function [ocont,RhoV2s,iscvg] = DMFT_Hubbard_Ex (U,mu,T,D,ozin,RhoV2in,Lambda,N,Nkeep) 2 | % < Description > 3 | % 4 | % [ocont,RhoV2s] = DMFT_Hubbard_Ex (U,mu,T,D,ozin,RhoV2in,Lambda,N,Nkeep) 5 | % 6 | % Perform the DMFT calculation of the one-band Hubbard model with the NRG 7 | % as an impurity solver. Here we consider a lattice (on which the Hubbard 8 | % model is defined) whose non-interacting density of states is semi-ellipse 9 | % of half-bandwidth D. Such density of states is known to come from the 10 | % Bethe lattice with infinite coordination number. 11 | % 12 | % < Input > 13 | % U, mu, T, D : [numeric] Parameters that define the Hubbard model. 14 | % Interaction strength, chemical potential, temperature, and the 15 | % half-bandwidth of the non-interacting density of states, 16 | % respectively. 17 | % ozin, RhoV2in : [vector] Initial hybridization function to start the 18 | % DMFT self-consistency loop. The function is assumed to be the 19 | % linear interpolation among the data points (ozin vs. RhoV2in), and 20 | % it is re-evaluted on the frequency grid "ocont" (see below); then 21 | % the re-evaluated data is fed into the logarithmic discretization 22 | % routine ("doCLD"). 23 | % Lambda, N, Nkeep : [numeric] NRG parameters. Logarithmic discretization 24 | % parameter, the maximum of the Wilson chain length, and the maximum 25 | % number of kept states, respectively. "Lambda" and "N" are directly 26 | % fed into "doCLD" and "Nkeep" into "NRG_IterDiag". 27 | % 28 | % < Output > 29 | % ocont : [vector] Frequency grid on which the hybridization functions 30 | % ("RhoV2s"; see below) are defined. Here we use the default output 31 | % of "getAcont". 32 | % RhoV2s : [matrix] Hybridization functions that are updated during the 33 | % DMFT self-consistency loop. At the n-th iteration of the loop (n = 34 | % 1, 2, 3, ...), RhoV2s(:,n) is used as the input (fed into "doCLD"). 35 | % The new hybridization function, as the result of the iteration by 36 | % using "getAdisc", "getAcont", "SEtrick", etc., is stored as 37 | % RhoV2s(:,n+1), which is directly used as the input for the next 38 | % iteration. The size of "RhoV2s" is numel(ocont)-by-(m+1), where m 39 | % is the number of DMFT iterations taken. 40 | % iscvg : [logical] If true, the DMFT self-consistency is achieved up to 41 | % a tolerance (set by "cvgth"; see inside the code). If false, the 42 | % self-consistency loop is terminated since it reached the maximnum 43 | % iteration index (set by "Ndmft"; see inside the code). 44 | % 45 | % Rewritten by S.Lee (Oct.28,2022): Revised for the TN lecture course at 46 | % SNU. 47 | 48 | % % default values of parameters 49 | Ndmft = 30; % maximum number of DMFT iterations 50 | 51 | % DMFT convergence criterion. If the difference between the old 52 | % hybridization function (the input to "doZLD") and the new hybridization 53 | % function (the output from a DMFT iteration) is smaller than "cvgth" for 54 | % all frequencies, the DMFT self-consistency is achieved. 55 | cvgth = 1e-3; 56 | % % % % % 57 | 58 | % % % % TODO (start) % % % % 59 | 60 | 61 | ocont = getAcont(0,0,0,0); 62 | RhoV2s = zeros(numel(ocont),Ndmft+1); 63 | iscvg = false; 64 | 65 | for itd = (1:Ndmft) 66 | [ff,gg] = doCLD(ocont,RhoV2s(:,itd),Lambda,N); 67 | 68 | % iterative diagonalization 69 | Inrg = NRG_IterDiag(H0,A0,Lambda,ff,F,gg,sum(NF,3),Z,Nkeep); 70 | 71 | Inrg = getRhoFDM(Inrg,T); 72 | 73 | [odisc,Adisc1] = getAdisc(Inrg,F(:,:,1),F(:,:,1),Z); 74 | [~ ,Adisc2] = getAdisc(Inrg,FHU(:,:,1),F(:,:,1),Z); 75 | 76 | [ocont,Acont1] = getAcont(odisc,Adisc1,log(Lambda),T/5); 77 | [~ ,Acont2] = getAcont(odisc,Adisc2,log(Lambda),T/5); 78 | 79 | SE = SEtrick(ocont,Acont1,Acont2); 80 | 81 | xi = ocont + mu - SE; 82 | Glat = (2/(D^2))*(xi - 1i*sqrt(D^2 - xi.^2)); 83 | Alat = (-1/pi)*imag(Glat); 84 | RhoV2s(:,itd+1) = ((D/2)^2)*Alat; 85 | 86 | if max(abs(RhoV2s(:,itd+1)-RhoV2s(:,itd)),[],1) < cvgth 87 | disptime('DMFT converged; exit the loop.'); 88 | iscvg = true; 89 | break; 90 | end 91 | end 92 | 93 | RhoV2s(:,itd+2:end) = []; 94 | 95 | % % % % TODO (end) % % % % 96 | 97 | 98 | end -------------------------------------------------------------------------------- /Tutorials/T17.2_DMFT_NRG/DMFT_NRG.m: -------------------------------------------------------------------------------- 1 | %% DMFT+NRG 2 | % Author: 3 | %% 4 | % In this tutorial, we will perform the dynamical mean-field theory (DMFT) calculations 5 | % by using our NRG code as an impurity solver. Such approach is called DMFT+NRG. 6 | % 7 | % _Note:_ The calculations for Exercises (b) and (c) will take quite long time; 8 | % it took about 50 minutes on my laptop. 9 | %% Exercise (a): Complete the DMFT+NRG function 10 | % There is a function |DMFT_Hubbard_Ex.m|, contained in the same sub-directory 11 | % together with this script. The function is designed to perforem DMFT+NRG calculations 12 | % on the Hubbard model on a lattice whose non-interacting density of states is 13 | % semi-elliptic, 14 | % 15 | % $$\rho(\epsilon) = \frac{2}{\pi D^2} \theta (D - |\epsilon|) \sqrt{D^2 - \epsilon^2} 16 | % .$$ 17 | % 18 | % Here we use $D :=1$ as the energy unit. Such semi-elliptic $\rho(\epsilon)$ 19 | % comes from the Bethe lattice with infinite coordination number. However, the 20 | % actual lattice geometry is not important here, since the only information on 21 | % the lattice relevant to this type of calculation is the non-interacting density 22 | % of states. 23 | % 24 | % Complete |DMFT_Hubbard_Ex.m|, by filling out the parts enclosed by the comments 25 | % |TODO (start)| and |TODO (end)|. 26 | %% 27 | % Let's consider the simplest example of $U = 0$ and $\mu = 0$. Actually, this 28 | % example is somehow trivial; the DMFT self-consistency loop completes in two 29 | % iterations regardless of the initial hybridization function. (*Quick exercise:* 30 | % why?) 31 | 32 | clear 33 | 34 | % system parameters 35 | U = 0; 36 | mu = 0; 37 | T = 1e-4; 38 | D = 1; 39 | 40 | % initial hybridization function 41 | ozin = [-1;1]; 42 | RhoV2in = [1;1]/2*(D/2)^2; 43 | 44 | % NRG parameters 45 | Lambda = 4; 46 | N = 30; 47 | Nkeep = 300; 48 | 49 | % run DMFT+NRG 50 | [ocont,RhoV2s,iscvg] = DMFT_Hubbard_Ex (U,mu,T,D,ozin,RhoV2in,Lambda,N,Nkeep); 51 | %% 52 | % Here I don't show the log message since it's too long. 53 | % 54 | % First check whether the DMFT self-consistency is achieved. 55 | 56 | disp(iscvg); 57 | %% 58 | % Let's plot the local spectral functions $A (\omega) = (2/D)^2 \Delta'' (\omega)$. 59 | % Note that this relation between $A(\omega)$ and $\Delta''(\omega)$ holds only 60 | % for the semi-elliptic $\rho(\epsilon)$ we've chosen. 61 | 62 | cmap = parula(round(size(RhoV2s,2)*1.2)); 63 | cmap = flipud(cmap(1:size(RhoV2s,2),:)); % to avoid too bright colors 64 | legs = cell(1,size(RhoV2s,2)); 65 | 66 | figure; 67 | hold on; 68 | for itd = (1:size(RhoV2s,2)) 69 | plot(ocont/D,RhoV2s(:,itd)/((D/2)^2)*(pi*D/2), ... 70 | 'LineWidth',1,'Color',cmap(itd,:)); 71 | legs{itd} = ['#',sprintf('%02i/%02i',[itd size(RhoV2s,2)])]; 72 | end 73 | hold off; 74 | grid on; 75 | set(gca,'LineWidth',1,'FontSize',13); 76 | legend(legs); 77 | xlabel('$\omega / D$','Interpreter','latex'); 78 | ylabel('$A(\omega) \cdot \pi D/2$','Interpreter','latex'); 79 | xlim([-1 1]*(2*D)); 80 | %% 81 | % Indeed, the converged spectral function equals to the non-interacting density 82 | % of states, i.e., $A(\omega) = \rho(\omega)$. That is, the DMFT is exact for 83 | % non-interacting systems. 84 | % 85 | % In the plot above, we multiplied $\pi D/2$ to the spectral functions so that 86 | % the converged curve takes a value of 1 at the Fermi level ($\omega = 0$); it's 87 | % in the same spirit as we multiplied $\pi \Delta_0$ in the previous tutorial 88 | % on the SIAM with a box-shaped hybridization function. 89 | %% Exercise (b): Obtain the DMFT+NRG solutions starting from the $U = 0$ result 90 | % Let's use the $U = 0$ result of the hybridization function as the initial 91 | % hybridization function for DMFT self-consistency loops. Obtain the DMFT+NRG 92 | % solutions of the Hubbard model at half filling (i.e., $\langle \hat{n}_i \rangle 93 | % = 1$), for several different values of $U/D = (2:0.3:3.5)$. Fix $T = 10^{-4} 94 | % D$ and $D := 1$. Plot the converged spectral functions. What's happening? Also, 95 | % discuss the convergence behaviors depending on $U$. 96 | %% Exercise (c): Obtain the DMFT+NRG solutions starting from the $U = 3.5 D$ result 97 | % Obtain the DMFT+NRG solutions for the same system parameters as used in Exercise 98 | % (b), except that we use the $U = 3.5D$ result of the hybridization function, 99 | % one of the results from Exercise (b) above, as the initial hybridization function, 100 | % instead of the $U = 0$ result. How do the converged spectral functions look 101 | % like, in comparison with the results of Exercise (b)? -------------------------------------------------------------------------------- /Tutorials/T17.2_DMFT_NRG/DMFT_NRG.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.2_DMFT_NRG/DMFT_NRG.mlx -------------------------------------------------------------------------------- /Tutorials/T17.2_DMFT_NRG/DMFT_NRG.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.2_DMFT_NRG/DMFT_NRG.pdf -------------------------------------------------------------------------------- /Tutorials/T17.2_DMFT_NRG_sol/DMFT_NRG_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.2_DMFT_NRG_sol/DMFT_NRG_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T17.2_DMFT_NRG_sol/DMFT_NRG_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T17.2_DMFT_NRG_sol/DMFT_NRG_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T18.1_TDVP_1site_ErrorAnalysis/TDVP_1site_ErrorAnalysis.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T18.1_TDVP_1site_ErrorAnalysis/TDVP_1site_ErrorAnalysis.mlx -------------------------------------------------------------------------------- /Tutorials/T18.1_TDVP_1site_ErrorAnalysis/TDVP_1site_ErrorAnalysis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T18.1_TDVP_1site_ErrorAnalysis/TDVP_1site_ErrorAnalysis.pdf -------------------------------------------------------------------------------- /Tutorials/T18.1_TDVP_1site_ErrorAnalysis_sol/TDVP_1site_ErrorAnalysis_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T18.1_TDVP_1site_ErrorAnalysis_sol/TDVP_1site_ErrorAnalysis_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T18.1_TDVP_1site_ErrorAnalysis_sol/TDVP_1site_ErrorAnalysis_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T18.1_TDVP_1site_ErrorAnalysis_sol/TDVP_1site_ErrorAnalysis_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T19.1_TDVP_2site_ErrorAnalysis/TDVP_2site_ErrorAnalysis.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.1_TDVP_2site_ErrorAnalysis/TDVP_2site_ErrorAnalysis.mlx -------------------------------------------------------------------------------- /Tutorials/T19.1_TDVP_2site_ErrorAnalysis/TDVP_2site_ErrorAnalysis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.1_TDVP_2site_ErrorAnalysis/TDVP_2site_ErrorAnalysis.pdf -------------------------------------------------------------------------------- /Tutorials/T19.1_TDVP_2site_ErrorAnalysis_sol/TDVP_2site_ErrorAnalysis_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Time-dependent variational principle (TDVP): 2-site variant 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for 2-site TDVP 4 | % The complete version is uploaded as |DMRG/TDVP_2site.m|. Compare with your 5 | % version! -------------------------------------------------------------------------------- /Tutorials/T19.1_TDVP_2site_ErrorAnalysis_sol/TDVP_2site_ErrorAnalysis_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.1_TDVP_2site_ErrorAnalysis_sol/TDVP_2site_ErrorAnalysis_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T19.1_TDVP_2site_ErrorAnalysis_sol/TDVP_2site_ErrorAnalysis_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.1_TDVP_2site_ErrorAnalysis_sol/TDVP_2site_ErrorAnalysis_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T19.2_EnergyVariance/EnergyVariance.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.2_EnergyVariance/EnergyVariance.mlx -------------------------------------------------------------------------------- /Tutorials/T19.2_EnergyVariance/EnergyVariance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.2_EnergyVariance/EnergyVariance.pdf -------------------------------------------------------------------------------- /Tutorials/T19.2_EnergyVariance/varE_2site_Ex.m: -------------------------------------------------------------------------------- 1 | function [varE,varE1,varE2] = varE_2site_Ex (M,Hs) 2 | % < Description > 3 | % 4 | % [varE,varE1,varE2] = varE_2site_Ex (M,Hs) 5 | % 6 | % Compute the two-site energy variance of a given MPS and and an MPO 7 | % Hamiltonian, following the recipe givin in Sec. IV of [A. Gleis, J.-W. 8 | % Li, and J. von Delft, arXiv:2207.13161 (2022)]. 9 | % 10 | % < Input > 11 | % M : [1 x N cell array] Matrix product state (MPS) as the initial guess of 12 | % the variational search. Each M{n} is a rank-3 tensor acting on site 13 | % n. Their legs are ordered as left-right-bottom(=physical). The 14 | % length M, i.e., numel(Hs), defines the system length N. 15 | % Hs : [1 x N cell array] Matrix product operator (MPO) of the Hamiltonian. 16 | % Each Hs{n} is a rank-4 tensor acting on site n. The order of legs 17 | % of Hs{n} is bottom-top-left-right, where the bottom (top) leg 18 | % contracts to the physical leg of bra (ket) tensor. 19 | % 20 | % < Output > 21 | % varE : [numeric] Sum of the all 1- and 2-site terms of the energy 22 | % variance. 23 | % varE1 : [1 x N numeric array] varE1(n) is the 1-site term of the energy 24 | % variance that involves the MPO tensor Hs{n}. 25 | % varE2 : [1 x (N-1) numeric array] varE2(n) is the 2-site term of the 26 | % energy variance that involves the MPO tensors Hs{n} and Hs{n+1}. 27 | % 28 | % Written by S.Lee (Nov.04,2022): the course at SNU. 29 | 30 | tobj = tic2; 31 | 32 | N = numel(M); 33 | 34 | % % sanity check for input 35 | if N < 2 36 | error('ERR: chain is too short.'); 37 | elseif numel(M) ~= numel(Hs) 38 | error('ERR: M has different lengths from that of Hs.'); 39 | end 40 | 41 | for itN = (1:N) 42 | if size(Hs{itN},1) ~= size(Hs{itN},2) 43 | error(['ERR: The first and second legs of Hs{', ... 44 | sprintf('%i',itN),'} have different dimensions.']); 45 | elseif size(Hs{itN},2) ~= size(M{itN},3) 46 | error(['ERR: The second leg of Hs{', ... 47 | sprintf('%i',itN),'} and the third leg of M{', ... 48 | sprintf('%i',itN),'} have different dimensions.']); 49 | end 50 | end 51 | % % % 52 | 53 | % bring into site-canonical form at site 1 54 | [M,S] = canonForm(M,1,[],[]); % no truncation 55 | 56 | % Contractions of MPO and MPS tensors that represent the effective 57 | % Hamiltonian for the left/right parts of the chain: When the orthogonality 58 | % center (= central tensor in a site-canonical form) is at site n, then 59 | % Hlr{m+1} for m < n (m > n) is the left (right) part of the effective 60 | % Hamiltonian made of M(1:m) and Hs(1:m) [M(m:end) and Hs(m:end)]. 61 | Hlr = cell(1,N+2); 62 | Hlr{1} = 1; % to initialize "zipper" contraction 63 | Hlr{end} = 1; % to represent the Hamiltonian for the dummy space 64 | 65 | % Since M is in right-canonical form by now (except for M{1}), Hlr{..} are 66 | % the right parts of the Hamiltonian. That is, Hlr{n+1} is the right part 67 | % of Hamiltonian which is obtained by contracting M(n:end) with Hs(n:end). 68 | % (Note the index for Hlr is n+1, not n, since Hlr{1} is dummy.) 69 | for itN = (N:-1:2) 70 | % permute left<->right, to make use of updateLeft 71 | T = permute(M{itN},[2 1 3]); 72 | Hlr{itN+1} = updateLeft(Hlr{itN+2},3,T,permute(Hs{itN},[1 2 4 3]),4,T); 73 | end 74 | 75 | % result arrays 76 | varE1 = zeros(1,N); % 1-site terms 77 | varE2 = zeros(1,N-1); % 2-site terms 78 | 79 | % % % % TODO (start) % % % % 80 | 81 | for itN = (1:N) 82 | 83 | end 84 | 85 | % % % % TODO (end) % % % % 86 | 87 | varE = sum(varE1) + sum(varE2); 88 | 89 | toc2(tobj,'-v'); 90 | chkmem; 91 | 92 | end -------------------------------------------------------------------------------- /Tutorials/T19.2_EnergyVariance_sol/EnergyVariance_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.2_EnergyVariance_sol/EnergyVariance_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T19.2_EnergyVariance_sol/EnergyVariance_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T19.2_EnergyVariance_sol/EnergyVariance_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T20.1_CBE_DMRG/CBE_DMRG.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T20.1_CBE_DMRG/CBE_DMRG.mlx -------------------------------------------------------------------------------- /Tutorials/T20.1_CBE_DMRG/CBE_DMRG.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T20.1_CBE_DMRG/CBE_DMRG.pdf -------------------------------------------------------------------------------- /Tutorials/T20.1_CBE_DMRG_sol/CBE_DMRG_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solutions] Controlled bond expansion (CBE) DMRG for ground state search 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for CBE-DMRG 4 | % The complete version is uploaded as |DMRG/DMRG_GS_CBE.m|. Compare with your 5 | % implementation! 6 | %% Solution to Exercise (b): Error analysis 7 | % We repeat the CBE-DMRG calculations for the free spinful fermions on a tight-binding 8 | % chain, for different values of |Nkeep|. We use the same initial MPS obtained 9 | % from the iterative diagonalization, with the lowest value of |Nkeep|. 10 | 11 | clear 12 | 13 | % system parameters 14 | t = 1; % hopping amplitude 15 | L = 30; % number of sites in a chain 16 | 17 | % CBE-DMRG parameters 18 | Nkeep = (50:50:300); 19 | Nsweep = 8; 20 | delta = 0.1; 21 | 22 | E0_exact = nonIntTB(ones(L-1,1)*t)*2; % *2 due to two spins 23 | 24 | % Local operators 25 | [F,Z,S,I] = getLocalSpace('FermionS'); 26 | 27 | % % MPO formulation of Hamiltonian 28 | % Hamiltonian tensor for each chain site 29 | Hloc = cell(6,6); 30 | Hloc(:) = {zeros(size(I))}; 31 | Hloc{1,1} = I; 32 | Hloc{2,1} = Z*F(:,:,1); 33 | Hloc{3,1} = Z*F(:,:,2); 34 | Hloc{4,1} = Hloc{2,1}'; 35 | Hloc{5,1} = Hloc{3,1}'; 36 | Hloc{6,2} = -t*F(:,:,1)'; 37 | Hloc{6,3} = -t*F(:,:,2)'; 38 | Hloc{6,4} = -t*F(:,:,1); 39 | Hloc{6,5} = -t*F(:,:,2); 40 | Hloc{6,6} = I; 41 | 42 | Hloc = cell2mat(reshape(Hloc,[1 1 size(Hloc,1) size(Hloc,2)])); 43 | 44 | % full chain 45 | Hs = cell(1,L); 46 | Hs(:) = {Hloc}; 47 | Hs{1} = Hs{1}(:,:,end,:); % choose the last components of the left leg 48 | Hs{end} = Hs{end}(:,:,:,1); % choose the first components of the right leg 49 | 50 | % initial MPS 51 | Minit = cell(1,L); 52 | 53 | Hprev = 1; % initialize Hamiltonian with 1, as we will use MPO 54 | Aprev = 1; % identity tensor for the dummy leg 55 | 56 | for itN = (1:L) 57 | % add new site 58 | Anow = getIdentity(Aprev,2,I,2,[1 3 2]); 59 | Hnow = updateLeft(Hprev,3,Anow,Hs{itN},4,Anow); 60 | 61 | Hmat = Hnow(:,:,1); 62 | [V,D] = eig((Hmat+Hmat')/2); 63 | [D,ids] = sort(diag(D),'ascend'); 64 | if itN < L 65 | Ntr = min([numel(D);Nkeep(1)]); 66 | else 67 | Ntr = 1; 68 | end 69 | V = V(:,ids(1:Ntr)); 70 | 71 | Anow = contract(Anow,3,2,V,2,1,[1 3 2]); 72 | 73 | Minit{itN} = Anow; 74 | 75 | Hprev = contract(Hnow,3,2,V,2,1); 76 | Hprev = contract(V',2,2,Hprev,3,1,[1 3 2]); 77 | Aprev = Anow; 78 | end 79 | %% 80 | % Run calculations. 81 | 82 | % result arrays 83 | E0s = zeros(1,numel(Nkeep)); 84 | Eiters = cell(1,numel(Nkeep)); 85 | dws = zeros(1,numel(Nkeep)); 86 | varEs = zeros(1,numel(Nkeep)); 87 | 88 | for itk = (1:numel(Nkeep)) 89 | [M,E0s(itk),Eiters{itk},~,dw] = DMRG_GS_CBE (Minit,Hs,Nkeep(itk),Nsweep,delta); 90 | dws(itk) = sum(dw(:,end)); 91 | varEs(itk) = varE_2site(M,Hs); 92 | end 93 | %% 94 | % Let's see how the variational energy decreases with iterations, for different 95 | % values of |Nkeep|. 96 | 97 | legs = cell(1,numel(Nkeep)); 98 | clrs = parula(round(numel(Nkeep)*1.2)); 99 | 100 | figure; 101 | hold on; 102 | for itk = (1:numel(Nkeep)) 103 | plot((1:numel(Eiters{itk}))/(L-1),Eiters{itk}(:)-E0_exact, ... 104 | 'Color',clrs(itk,:),'LineWidth',1); 105 | legs{itk} = sprintf('Nkeep = %i',Nkeep(itk)); 106 | end 107 | hold off; 108 | set(gca,'XScale','Linear','YScale','log','FontSize',13,'LineWidth',1); 109 | xlim([0 2*Nsweep]); 110 | grid on; 111 | xlabel('# of sweeps'); 112 | ylabel('Ground-state energy error'); 113 | legend(legs); 114 | %% 115 | figure; 116 | hold on; 117 | plot(dws,E0s-E0_exact,'LineWidth',1,'Marker','x','MarkerSize',12); 118 | plot(varEs,E0s-E0_exact,'LineWidth',1,'Marker','+','MarkerSize',12); 119 | set(gca,'XScale','log','YScale','log','FontSize',13,'LineWidth',1); 120 | grid on; 121 | ylabel('Ground-state energy error'); 122 | legend({'vs. discarded weight','vs. 2-site variance'},'Location','northwest'); 123 | %% 124 | % We find that the ground-state energy error scales linearly against both the 125 | % discarded weight and the two-site variance. -------------------------------------------------------------------------------- /Tutorials/T20.1_CBE_DMRG_sol/CBE_DMRG_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T20.1_CBE_DMRG_sol/CBE_DMRG_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T20.1_CBE_DMRG_sol/CBE_DMRG_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T20.1_CBE_DMRG_sol/CBE_DMRG_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T21.1_finite_PEPS/contract_finPEPS_Ex.m: -------------------------------------------------------------------------------- 1 | function res = contract_finPEPS_Ex (T,Nkeep,Nsweep) 2 | % < Description > 3 | % 4 | % res = contract_finPEPS_Ex (T,Nkeep,Nsweep) 5 | % 6 | % Contract the reduced tensors on a finite square lattice with open 7 | % boundary conditions, by using the MPO-MPS method. That is, the first row 8 | % of the tensor array is regarded as an MPS (with fat bonds and physical 9 | % legs), and the second, third, etc. rows are absorbed into the firt row 10 | % sequentially, by using the variational multiplication implemented in 11 | % DMRG/mtimes_MPO.m. Note that in "mtimes_MPO" an MPO is multiplied with 12 | % the other MPO, not MPS. But here an MPO whose up legs have all singleton 13 | % dimentions can be regarded as an MPS, so we can use the function. 14 | % 15 | % < Input > 16 | % T : [cell array] T{m,n} is a rank-4 reduced tensor, obtained by 17 | % contracting a rank-5 tensor at site (m,n) from the projected 18 | % entangled-pair state (PEPS) as a ket state and the tensor's complex 19 | % conjugate. If an expectation value of a local operator or a product 20 | % of local operators is to be measured, then those local operators 21 | % are sandwiched between the physical legs of the rank-5 tensor and 22 | % its conjugate. 23 | % The legs of each T{m,n} are ordered as left-up-down-right. 24 | % Nkeep : [numeric] The maximum bond dimension along the horizontal 25 | % direction. 26 | % Nsweep : [numeric] Number of sweeps to be performed in each of MPO-MPS 27 | % multiplication. This parameter is handed over to "mtimes_MPO" used 28 | % as a sub-function here. 29 | % 30 | % < Output > 31 | % res : [numeric] Contraction result. 32 | % 33 | % Written by S.Lee (Nov.13,2022): for the lecture course at SNU. 34 | 35 | tobj = tic2; 36 | 37 | % sanity check 38 | for it1 = (1:size(T,1)) 39 | for it2 = (1:size(T,2)) 40 | if (it1 < size(T,1)) && (size(T{it1,it2},3) ~= size(T{it1+1,it2},2)) 41 | error(['ERR: The down leg of T{',sprintf('%i,%i',it1,it2), ... 42 | '} and the up leg of T{',sprintf('%i,%i',it1+1,it2),'} do not match.']) 43 | elseif (it2 < size(T,2)) && (size(T{it1,it2},4) ~= size(T{it1,it2+1},1)) 44 | error(['ERR: The right leg of T{',sprintf('%i,%i',it1,it2), ... 45 | '} and the left leg of T{',sprintf('%i,%i',it1,it2+1),'} do not match.']) 46 | elseif (it1 == 1) && (size(T{it1,it2},2) ~= 1) 47 | error(['ERR: The up leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 48 | elseif (it1 == size(T,1)) && (size(T{it1,it2},3) ~= 1) 49 | error(['ERR: The down leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 50 | elseif (it2 == 1) && (size(T{it1,it2},1) ~= 1) 51 | error(['ERR: The left leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 52 | elseif (it2 == size(T,2)) && (size(T{it1,it2},4) ~= 1) 53 | error(['ERR: The right leg of T{',sprintf('%i,%i',it1,it2),'} has non-singleton dimension.']); 54 | end 55 | end 56 | end 57 | % % % 58 | 59 | disptime(['Contract tensors on a ',sprintf('%i x %i',[size(T,1) size(T,2)]), ... 60 | ' lattice, with Nkeep = ',sprintf('%i',Nkeep)]); 61 | 62 | % % permute legs of T{..}, to use DMRG/mtimes_MPO 63 | for itN = (1:numel(T)) 64 | T{itN} = permute(T{itN},[3 2 1 4]); % down-up-left-right 65 | end 66 | 67 | % reduced tensors are not strictly normalized, so their contraction can 68 | % lead to very small or large numbers. In such cases, numerical procedures 69 | % can be unstable; sometimes one gets just 0 or Inf. To avoid this, 70 | % separate the norm of the contracted MPO after each step, and collect the 71 | % norms as the sum of their logarithms. 72 | logNorm = 0; 73 | 74 | % first row of reduced tensors as an MPO 75 | T2 = T(1,:); 76 | 77 | % % % % TODO (start) % % % % 78 | for it1 = (2:size(T,1)-1) 79 | 80 | end 81 | 82 | % contract the contraction result of the rows so far (all but except the 83 | % last row) and the last row 84 | 85 | 86 | % % % % TODO (end) % % % % 87 | 88 | % restore the separted norm 89 | res = res*exp(logNorm); 90 | 91 | toc2(tobj,'-v'); 92 | 93 | end -------------------------------------------------------------------------------- /Tutorials/T21.1_finite_PEPS/finite_PEPS.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T21.1_finite_PEPS/finite_PEPS.mlx -------------------------------------------------------------------------------- /Tutorials/T21.1_finite_PEPS/finite_PEPS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T21.1_finite_PEPS/finite_PEPS.pdf -------------------------------------------------------------------------------- /Tutorials/T21.1_finite_PEPS_sol/finite_PEPS_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T21.1_finite_PEPS_sol/finite_PEPS_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T21.1_finite_PEPS_sol/finite_PEPS_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T21.1_finite_PEPS_sol/finite_PEPS_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T22.1_iPEPS_CTMRG/iPEPS_CTMRG.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T22.1_iPEPS_CTMRG/iPEPS_CTMRG.mlx -------------------------------------------------------------------------------- /Tutorials/T22.1_iPEPS_CTMRG/iPEPS_CTMRG.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T22.1_iPEPS_CTMRG/iPEPS_CTMRG.pdf -------------------------------------------------------------------------------- /Tutorials/T22.1_iPEPS_CTMRG_sol/iPEPS_CTMRG_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Infinite PEPS (iPEPS): corner transfer matrix (CTM) 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for the symmetric CTMRG 4 | % The complete version is uploaded as |PEPS/symCTMRG.m|. Compare with your version! -------------------------------------------------------------------------------- /Tutorials/T22.1_iPEPS_CTMRG_sol/iPEPS_CTMRG_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T22.1_iPEPS_CTMRG_sol/iPEPS_CTMRG_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T22.1_iPEPS_CTMRG_sol/iPEPS_CTMRG_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T22.1_iPEPS_CTMRG_sol/iPEPS_CTMRG_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T23.1_SimpleUpdate_TRG/SimpleUpdate_TRG.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T23.1_SimpleUpdate_TRG/SimpleUpdate_TRG.mlx -------------------------------------------------------------------------------- /Tutorials/T23.1_SimpleUpdate_TRG/SimpleUpdate_TRG.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T23.1_SimpleUpdate_TRG/SimpleUpdate_TRG.pdf -------------------------------------------------------------------------------- /Tutorials/T23.1_SimpleUpdate_TRG_sol/SimpleUpdate_TRG_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solutions] Simple update and tensor renormalization group 2 | % Author: 3 | %% Solutions to Exercise (a): Complete the function for the simple update method on a honeycomb lattice; and Exercise (b): Complete the function for the TRG on a honeycomb lattice 4 | % The complete versions are uploaded as |PEPS/SimpleUp_Honeycomb.m| and |PEPS/TRG_Honeycomb.m|. 5 | % Compare with your implementation! -------------------------------------------------------------------------------- /Tutorials/T23.1_SimpleUpdate_TRG_sol/SimpleUpdate_TRG_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T23.1_SimpleUpdate_TRG_sol/SimpleUpdate_TRG_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T23.1_SimpleUpdate_TRG_sol/SimpleUpdate_TRG_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T23.1_SimpleUpdate_TRG_sol/SimpleUpdate_TRG_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T24.1_GILT/GILT.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T24.1_GILT/GILT.mlx -------------------------------------------------------------------------------- /Tutorials/T24.1_GILT/GILT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T24.1_GILT/GILT.pdf -------------------------------------------------------------------------------- /Tutorials/T24.1_GILT_sol/GILT_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Graph-independent local truncations (GILT) 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for the TRG and the GILT for a square lattice 4 | % The complete version is uploaded as |PEPS/TRG_GILT_Square.m|. Compare with 5 | % your implementation! -------------------------------------------------------------------------------- /Tutorials/T24.1_GILT_sol/GILT_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T24.1_GILT_sol/GILT_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T24.1_GILT_sol/GILT_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T24.1_GILT_sol/GILT_sol.pdf -------------------------------------------------------------------------------- /Tutorials/T25.1_MachineLearning/MNIST_train.csv.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T25.1_MachineLearning/MNIST_train.csv.zip -------------------------------------------------------------------------------- /Tutorials/T25.1_MachineLearning/MachineLearning.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T25.1_MachineLearning/MachineLearning.mlx -------------------------------------------------------------------------------- /Tutorials/T25.1_MachineLearning/MachineLearning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T25.1_MachineLearning/MachineLearning.pdf -------------------------------------------------------------------------------- /Tutorials/T25.1_MachineLearning_sol/MachineLearning_sol.m: -------------------------------------------------------------------------------- 1 | %% [Solution] Machine learning with MPS 2 | % Author: 3 | %% Solution to Exercise (a): Complete the function for the MPS-based machine learning method 4 | % The complete version is uploaded as |ML/ML_MPS.m|. Compare with your implementation! 5 | %% 6 | % This is the last tutorial exercise throughout this lecture course. If you 7 | % have found any bugs, mistakes, typos, etc. from the tutorial materials so far, 8 | % please contact us. Thank you for your participation! -------------------------------------------------------------------------------- /Tutorials/T25.1_MachineLearning_sol/MachineLearning_sol.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T25.1_MachineLearning_sol/MachineLearning_sol.mlx -------------------------------------------------------------------------------- /Tutorials/T25.1_MachineLearning_sol/MachineLearning_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/Tutorials/T25.1_MachineLearning_sol/MachineLearning_sol.pdf -------------------------------------------------------------------------------- /Util/KKi2r.m: -------------------------------------------------------------------------------- 1 | function yr = KKi2r (xi, yi, varargin) 2 | % < Description > 3 | % 4 | % yr = KKi2r (xi, yi [,option]) 5 | % 6 | % Convert the imaginary part of a causal function into the real part, by 7 | % using the Kramers-Kronig relation. If the input is the real part, then 8 | % yi = -KKi2r(xr,yr) yields the imaginary part. 9 | % This function computes the Cauchy principal value (also called principal 10 | % value integral) 11 | % yr (xr) = (1/pi) * P. \int_{-\infty}^{\infty} dx yi(x) / (x-xr) , 12 | % where P. means the principal value and yi(x), yr(xr) are the functions 13 | % corresponding to the discrete data (xi, yi), (xi, yr), respectively. The 14 | % integration is done numerically, assuming that the input function is the 15 | % linear interpolation among the points (xi, yi) on the interval [xi(1), 16 | % xi(end)], and have 1/x tails on (-\infty, xi(1)) and (xi(end), \infty) 17 | % extrapolated from (xi(1), yi(1) and (xi(end), yi(end)), respectively. 18 | % 19 | % < Input > 20 | % xi : [vector] Grid points of x values on which the imaginary part(s) of 21 | % the causal function(s) are defined. 22 | % yi : [vector, matrix, or multi-dimensional array] The imaginary part(s) 23 | % of the causal function(s) on the grid given by "xi". Each column of 24 | % "yi" corresponds to a function, representing the imaginary part 25 | % of a function as a piecewise linear function connecting the (x,y) 26 | % pairs specified xi and the column elements. numel(xi) == size(yi,1) 27 | % should hold. 28 | % 29 | % < Output > 30 | % yr : [vector, matrix, or multi-dimensional array] The real part(s) of the 31 | % causal function(s) on the grid specifed by xi. It has the same 32 | % structure as the input "yi"; each column of "yr" corresponds to the 33 | % column of yi with the same column index. 34 | % 35 | % Rewritten by S.Lee (Oct.28,2022): Revised for the TN lecture course at 36 | % SNU. 37 | 38 | % % % sanity check 39 | if isvector(xi) 40 | xi = xi(:); 41 | else 42 | error('ERR: input frequency ''xi'' is not a vector.'); 43 | end 44 | if isvector(yi) 45 | yi = yi(:); 46 | end 47 | if numel(xi) ~= size(yi,1) 48 | error('ERR: numel(xi) ~= size(yi,1)'); 49 | end 50 | 51 | sz = size(yi); % save the size for future reshaping 52 | yi = yi(:,:); % make yi to matrix; reshape later 53 | 54 | if any(diff(xi) < 0) 55 | disptime('WRN: input ''xi'' is not in ascending order.'); 56 | [xi,ids] = sort(xi,'ascend'); 57 | yi = yi(ids,:); 58 | end 59 | if any(diff(xi) == 0) 60 | error('ERR: Input ''xi'' is not unique.'); 61 | end 62 | % % % % 63 | 64 | dxi = diff(xi); 65 | a = (yi(2:end,:) - yi(1:end-1,:))./dxi; % piecewise slope 66 | b = (-xi(1:end-1).*yi(2:end,:)+xi(2:end).*yi(1:end-1,:))./dxi; % piecewise y intercept 67 | 68 | ids = find(xi ~= 0); % to be used for adding the tail contributions 69 | 70 | yr = zeros(size(yi)); % result array 71 | 72 | % % % % TODO (start) % % % % 73 | 74 | % Contribution of a piecewise linear segment y = (a*x+b) over [x1,x2] to 75 | % the point at x0 is given by the integral of (a*x+b)/(x-x0) over [x1,x2]: 76 | % a*(x2-x1) + (a*x0+b)*log(abs((x2-x0)/(x1-x0))) --- (1) 77 | % Since a = (y2-y1)/(x2-x1), y1 = a*x1+b, and y2 = a*x2+b, the sum of the 78 | % first terms will be yi(end)-yi(1). 79 | 80 | % contribution from the second term of Eq. (1) 81 | for it = (1:numel(xi)) 82 | yr(it,:) = sum( (a(1:it-2,:)*xi(it)+b(1:it-2,:)).* ... 83 | log((xi(it)-xi(2:it-1,:))./(xi(it)-xi(1:it-2,:))) , 1) + ... 84 | sum( (a(it+1:end,:)*xi(it)+b(it+1:end,:)).* ... 85 | log((xi(it+2:end,:)-xi(it))./(xi(it+1:end-1,:)-xi(it))) , 1); 86 | end 87 | yr(2:end-1,:) = yr(2:end-1,:) + yi(2:end-1,:).*log(abs(dxi(2:end)./dxi(1:end-1))); 88 | 89 | % contribution from the first term of Eq. (1) 90 | yr = yr + (yi(end,:)-yi(1,:)); 91 | 92 | % contribution from a 1/x tail (= y1*x1/x stretching from the point (x1,y1) at the edge) to point at x0: 93 | % \int_{x1}^{inf} dx (y1*x1/x) * (1/(x-x0)) = (y1*x1/x0)*log(abs(x1/(x1-x0))) --- (2) 94 | 95 | % from the right tail 96 | yr(ids(1:end-1),:) = yr(ids(1:end-1),:) + ... 97 | xi(end)*log(xi(end)./(xi(end)-xi(ids(1:end-1)))).*(yi(end,:)./xi(ids(1:end-1))); 98 | 99 | % from the left tail: end <-> 1 / takes opposite sign (-1) to the 100 | % contribution to yr(1:end-1) due to opposite integration interval [-inf, x1] 101 | yr(ids(2:end),:) = yr(ids(2:end),:) - ... 102 | xi(1)*log(xi(1)./(xi(1)-xi(ids(2:end)))).*(yi(1,:)./xi(ids(2:end))); 103 | 104 | % at zero frequency 105 | yr(xi == 0,:) = yr(xi == 0,:) + (yi(end,:)-yi(1,:)); 106 | 107 | % at the edges: the sum of the second term in Eq.(1) and the term in 108 | % Eq.(2). The divergent terms are cancelled out. 109 | yr(end,:) = yr(end,:) + yi(end,:)*log(xi(end)/dxi(end)); 110 | yr(1,:) = yr(1,:) - yi(1,:)*log(abs(xi(1)/dxi(1))); % opposite sign simliarly as for yr(2:end) 111 | 112 | yr = yr/pi; % factor 1/pi due to the definition of KK relation 113 | 114 | % % % % TODO (end) % % % % 115 | 116 | if ~isequal(size(yr),sz) 117 | yr = reshape(yr,sz); 118 | end 119 | 120 | % catch e 121 | % disp2(getReport(e)) 122 | % disp2('Let''s Debug!'); 123 | % keyboard; 124 | % end 125 | 126 | end -------------------------------------------------------------------------------- /Util/byte2read.m: -------------------------------------------------------------------------------- 1 | function str = byte2read (inbyte, varargin) 2 | % < Description > 3 | % 4 | % str = byte2read (inbyte [, 'fmt', ..] [, 'k', ..]) 5 | % 6 | % Convert input data size in bytes to human readable size using TB, GB, MB, 7 | % KB, B (decimal, 1000) or 'TiB','GiB','MiB','KiB','B' (binary, 1024). 8 | % 9 | % < Input > 10 | % inbyte : [numeric] Byte. 11 | % 12 | % < Option > 13 | % 'fmt', .. : [string] Format spec to convert number to string. (Default : '%.2f') 14 | % 'k', .. : [integer] Set 1000 to use kB, MB, GB, ...; or set 1024 to use 15 | % KiB, MiB, GiB, ...) 16 | % (Default: 1000 for linux & mac, 1024 for Windows) 17 | % 18 | % < Output > 19 | % str : [string] String describing data size. 20 | % 21 | % Written by S.Lee (2015) 22 | % Updated by S.Lee (May 05,2017) 23 | % Updated by S.Lee (Apr.17,2019): Cleaned code up. 24 | 25 | % default value of options 26 | fmt = '%.2f'; 27 | if ismember(computer,{'GLNXA64','MACI64'}) 28 | kunit = 1000; 29 | else % for windows 30 | kunit = 1024; 31 | end 32 | 33 | % parse options 34 | while ~isempty(varargin) 35 | switch varargin{1} 36 | case 'fmt' 37 | fmt = varargin{2}; 38 | varargin(1:2) = []; 39 | case 'k' 40 | kunit = varargin{2}; 41 | varargin(1:2) = []; 42 | otherwise 43 | error('ERR: cannot interpret option.'); 44 | end 45 | end 46 | 47 | % sanity check for kunit 48 | if ~any(kunit == [1000 1024]) 49 | error('ERR: Value for ''k'' should be either 1000 or 1024.'); 50 | end 51 | 52 | if kunit == 1000 % Linux and Mac 53 | strunits = {'B','kB','MB','GB','TB'}; 54 | else %if kunit == 1024 % Windows 55 | strunits = {'B','KiB','MiB','GiB','TiB'}; 56 | end 57 | 58 | kpow = floor(log(inbyte)/log(kunit)); 59 | if kpow > (numel(strunits)-1) 60 | kpow = numel(strunits)-1; 61 | elseif kpow < 0 62 | kpow = 0; 63 | end 64 | 65 | str = [sprintf(fmt,inbyte/(kunit^kpow)),strunits{kpow+1}]; 66 | 67 | end -------------------------------------------------------------------------------- /Util/chkmem.m: -------------------------------------------------------------------------------- 1 | function varargout = chkmem (varargin) 2 | % < Description > 3 | % 4 | % chkmem (['thval', ..] [, 'fmt', ..]) % display message on screen 5 | % membyte = chkmem (['thval', ..] [, 'fmt', ..]) % suppress message 6 | % 7 | % Check the memory usage of a current MATLAB program (via system command 8 | % 'ps' for Mac and Linux, or matlab command 'memory' in Windows). If the 9 | % usage is larger than a threshold, show the message. 10 | % 11 | % < Option > 12 | % 'thval', .. : [numeric] Threshold of memory usage (in byte) to show the 13 | % memory usage. (Default: 0, i.e., show always.) 14 | % 'fmt', .. : [string] Format spec to convert number to string. (Default : '%.2f') 15 | % 16 | % < Output > 17 | % membyte : [numeric] Memory usage in bytes. If output is specified, 18 | % the function does not display the message on screen. 19 | % 20 | % Written by S.Lee (2015) 21 | % Updated by S.Lee (May 05,2017) 22 | % Updated by S.Lee (Apr.17,2019): Cleaned code up. 23 | 24 | % default option 25 | thval = 0; 26 | kunit = 1024; % currently, all the plaforms are using 1024 for RAM, to my knowledge 27 | fmt = '%.2f'; 28 | 29 | % parse option 30 | while ~isempty(varargin) 31 | switch varargin{1} 32 | case 'fmt' 33 | fmt = varargin{2}; 34 | varargin(1:2) = []; 35 | case 'thval' 36 | thval = varargin{2}; 37 | varargin(1:2) = []; 38 | otherwise 39 | error('ERR: cannot interpret option.'); 40 | end 41 | end 42 | 43 | if strcmp(computer,'MACI64') || strcmp(computer,'GLNXA64') % for Mac or Linux 44 | mypid = feature('getpid'); 45 | [isok,val] = system(['ps -p ',sprintf('%i',mypid),' -o rss | tail -n 1']); 46 | 47 | if isok == 0 48 | membyte = str2double(val)*kunit; 49 | else 50 | warning('WRN: failed to retreive memory usage from ''ps''.'); 51 | membyte = 0; 52 | end 53 | else % for Windows 54 | meminfo = memory; 55 | membyte = meminfo.MemUsedMATLAB; 56 | end 57 | 58 | if nargout 59 | varargout = {membyte}; 60 | else 61 | str = disptime(['Memory usage : ',byte2read(membyte,'k',kunit,'fmt',fmt),'\n']); 62 | if membyte > thval 63 | fprintf(str); 64 | end 65 | end 66 | 67 | end -------------------------------------------------------------------------------- /Util/disptime.m: -------------------------------------------------------------------------------- 1 | function varargout = disptime (varargin) 2 | % < Description > 3 | % 4 | % disptime % display timestamp only 5 | % disptime (str) % display message (timestamp + str) on screen 6 | % timeval = disptime (str) % suppress message 7 | % 8 | % Display "current time (i.e. timestamp) + input string". Write the string 9 | % on the file if file name is given. Timestamp format is 'yy-mm-dd 10 | % HH:MM:SS'. 11 | % 12 | % < Input > 13 | % str : [string] String to display together with timestamp. 14 | % 15 | % < Output > 16 | % timeval : [string] Input string + current time. If output is specified 17 | % (e.g. command such as "res = disptime;" is used), the function does 18 | % not display the message on screen. 19 | % 20 | % Written by S.Lee (2015) 21 | % Updated by S.Lee (May 05,2017) 22 | % Updated by S.Lee (Apr.17,2019): Cleaned code up. 23 | 24 | if nargin 25 | if ischar(varargin{1}) 26 | str = varargin{1}; 27 | elseif isnumeric(varargin{1}) 28 | str = num2str(varargin{1}); 29 | else 30 | error('ERR: Unknown input.'); 31 | end 32 | 33 | res = [datestr(now,'yy-mm-dd HH:MM:SS'),' | ',str]; 34 | else 35 | res = datestr(now,'yy-mm-dd HH:MM:SS'); 36 | end 37 | 38 | if nargout 39 | varargout = {res}; 40 | else 41 | disp(res); 42 | end 43 | 44 | end -------------------------------------------------------------------------------- /Util/nonIntTB.m: -------------------------------------------------------------------------------- 1 | function [E_G, d_G, e_1p] = nonIntTB (t) 2 | % < Description > 3 | % 4 | % [E_G, d_G, e_1p] = nonIntTB (t) 5 | % 6 | % Compute the energy and degeneracy of the many-body ground state of 7 | % non-interacting spinless fermions on a tight-binding chain. The input 8 | % parameterizes the hopping amplitudes. 9 | % 10 | % t : [numeric vector] Each element -t(n) indicates a hopping amplitude 11 | % from site n to site n+1. The length of the vector numel(t) plus 1 12 | % defines the number of chain sites. 13 | % 14 | % < Output > 15 | % E_G : [numeric scalar] Ground-state energy, given by the sum of negative 16 | % elements of the single-particle eigen-energies "e_1p" (see below). 17 | % d_G : [numeric scalar] Ground-state degeneracy, given by 2^(number of 18 | % zero elements of "e_1p"). Here the zero elements are identified up 19 | % to numerical precision noise. 20 | % e_1p : [numeric vector] Eigenvalues of the single-particle Hamiltonian in 21 | % an ascending order. 22 | % 23 | % Written by S.Lee (Sep.02,2022) 24 | 25 | % single-particle Hamiltonian 26 | H_1p = diag(-t,-1); % sign factor -1 in -t as convention; the 1st diagonal below the main diagonal describes the forward hoppings 27 | H_1p = H_1p + H_1p'; % Hermitianize 28 | e_1p = sort(eig(H_1p),'ascend'); 29 | e_1p(abs(e_1p) < 10*size(H_1p,1)*max(eps(H_1p(:)))) = 0; % elements smaller than numerical precision noise are de facto zeros 30 | 31 | E_G = sum(e_1p(e_1p < 0)); % ground-state energy 32 | d_G = 2^(sum(e_1p == 0)); % degeneracy 33 | 34 | end -------------------------------------------------------------------------------- /Util/tic2.m: -------------------------------------------------------------------------------- 1 | function tobj = tic2 2 | % < Description > 3 | % 4 | % tobj = tic2 5 | % 6 | % Create a timer object (struct) to measure both real and CPU times. 7 | % 8 | % < Output > 9 | % tobj : [struct] Timer object. This will be the input for 'toc2' function. 10 | % .real : [uint8] Internal timer for built-in functions 'tic' and 'toc'. 11 | % .cpu : [double] Time in seconds after the current session of MATLAB 12 | % started. 13 | % 14 | % Written by S.Lee (May 05,2017) 15 | 16 | tobj = struct; 17 | tobj.real = tic; 18 | tobj.cpu = cputime; 19 | 20 | end -------------------------------------------------------------------------------- /Util/toc2.m: -------------------------------------------------------------------------------- 1 | function [realt,cput,avgcore] = toc2 (tobj,varargin) 2 | % < Description > 3 | % 4 | % [realt,cput,avgcore] = toc2 (tobj [,'-v']) 5 | % 6 | % Count real time (in sec), CPU time (in sec), and the average number of 7 | % cores used after the timer object 'tobj' is created by function 'tic2'. 8 | % 9 | % < Input > 10 | % tobj : [struct] Timer object. Refer to 'tic2' for detail. 11 | % 12 | % < Option > 13 | % '-v' : Option to display results. 14 | % 15 | % < Output > 16 | % realt : [double] Real time in seconds. 17 | % cput : [double] CPU time in seconds. 18 | % avgcore : [double] Average number of cores used. avgcore = cput/realt. 19 | % 20 | % Written by S.Lee (May 05,2017) 21 | % Updated by S.Lee (Apr.17,2019): Cleaned code up. 22 | 23 | oshow = false; 24 | 25 | % % parsing option 26 | while ~isempty(varargin) 27 | switch varargin{1} 28 | case '-v' 29 | oshow = true; 30 | varargin(1) = []; 31 | otherwise 32 | error('ERR: Unknown option.'); 33 | end 34 | end 35 | % % % 36 | 37 | realt = toc(tobj.real); 38 | cput = cputime - tobj.cpu; 39 | avgcore = cput/realt; 40 | 41 | if oshow 42 | fprintf(['Elapsed time: ',sprintf('%.4g',realt),'s, CPU time: ', ... 43 | sprintf('%.4g',cput),'s, Avg # of cores: ', ... 44 | sprintf('%.4g',avgcore),'\n']); 45 | end 46 | 47 | end -------------------------------------------------------------------------------- /readme.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/readme.mlx -------------------------------------------------------------------------------- /readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssblee/TensorNetworks2022/7b414679bdbcbca3ab90c87db56a02c70398c628/readme.pdf -------------------------------------------------------------------------------- /startup.m: -------------------------------------------------------------------------------- 1 | % < Description > 2 | % startup.m for the lecture course "Tensor Networks". It 3 | % (i) resets the path; 4 | % (ii) add the subdirectories of the directory (in which this 'startup.m' 5 | % file lies) to the path; 6 | % (iii) clear variables in workspace; 7 | % (iv) and show a startup message. 8 | % 9 | % Written by S.Lee (Apr.21,2017) 10 | % Rewritten by S.Lee (Aug.31,2022) 11 | % Updated by S.Lee (Nov.23,2022): Add one more sub-directory "ML". 12 | 13 | % % Reset path 14 | % temporarily turn off warning; if warning is not turned off above, MATLAB 15 | % might give warning 16 | warning('off','MATLAB:dispatcher:pathWarning'); 17 | restoredefaultpath; % reset path to default 18 | warning('on','MATLAB:dispatcher:pathWarning'); % turn on warning back 19 | % NOTE: if you want to keep custom path besides TN folder, comment out the 20 | % above three commands. 21 | 22 | % % Add to path 23 | fpath = fileparts(mfilename('fullpath')); % the TN directory in which this "startup.m" lies 24 | addpath(fpath); 25 | dirnames = {'MyWork','Util','Tensor','NRG','DMRG','PEPS','ML','Tutorials'}; % sub-directories 26 | for it1 = (1:numel(dirnames)) 27 | fpath2 = [fpath,filesep,dirnames{it1}]; 28 | if exist(fpath2,'dir') 29 | addpath(genpath(fpath2)); % add sub-directories to path 30 | end 31 | addpath(genpath(fpath2)); 32 | end 33 | 34 | % % Clear variables in memory 35 | clear 36 | 37 | % % startup messeage 38 | fprintf('startup.m | "Tensor Networks" tutorial material\n'); 39 | chkmem; 40 | --------------------------------------------------------------------------------