From a0cf7caab3344292b210cfe398801a4db52f0eef Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Uni-PC)" Date: Thu, 19 Apr 2018 11:53:00 +0200 Subject: [PATCH 01/50] adding the module entaglement to the libraries, basically copied from Francesco. --- Libraries/Modules/Compile | 6 +- Libraries/Modules/entanglement.f90 | 248 +++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 Libraries/Modules/entanglement.f90 diff --git a/Libraries/Modules/Compile b/Libraries/Modules/Compile index 6db49620..49f26f6f 100644 --- a/Libraries/Modules/Compile +++ b/Libraries/Modules/Compile @@ -1,16 +1,16 @@ OBJS=mat_mod.o Random_Wrap.o errors.o Files_mod.o maxent.o matrix.o maxent_stoch.o fourier.o \ Histogram.o lattices_v3.o Natural_constants.o log_mesh.o precdef.mod.o \ - Histogram_v2.o Mat_subroutines.o + Histogram_v2.o Mat_subroutines.o entanglement.o $(LIB): $(OBJS) ar -r $(LIB) $(OBJS) %.o: %.f90 - $(FC) $(FLAGS) -c $< + $(FC) $(FLAGS) -c -cpp $< %.o: %.F90 - $(FC) $(FLAGS) -c $< + $(FC) $(FLAGS) -c -cpp $< errors.o: mat_mod.o diff --git a/Libraries/Modules/entanglement.f90 b/Libraries/Modules/entanglement.f90 new file mode 100644 index 00000000..ee2fd543 --- /dev/null +++ b/Libraries/Modules/entanglement.f90 @@ -0,0 +1,248 @@ +! Copyright (C) 2018 The ALF project +! +! The ALF project is free software: you can redistribute it and/or modify +! it under the terms of the GNU General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! The ALF project is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU General Public License for more details. +! +! You should have received a copy of the GNU General Public License +! along with Foobar. If not, see http://www.gnu.org/licenses/. +! +! Under Section 7 of GPL version 3 we require you to fulfill the following additional terms: +! +! - It is our hope that this program makes a contribution to the scientific community. Being +! part of that community we feel that it is reasonable to require you to give an attribution +! back to the original authors if you have benefitted from this program. +! Guidelines for a proper citation can be found on the project's homepage +! http://alf.physik.uni-wuerzburg.de . +! +! - We require the preservation of the above copyright notice and this license in all original files. +! +! - We prohibit the misrepresentation of the origin of the original source files. To obtain +! the original source files please visit the homepage http://alf.physik.uni-wuerzburg.de . +! +! - If you make substantial changes to the program we require you to either consider contributing +! to the ALF project or to mark your material in a reasonable way as different from the original version. + + Module entanglement + +!-------------------------------------------------------------------- +!> @author +!> ALF-project +! +!> @brief +!> This module generates one and two dimensional Bravais lattices. +! +!-------------------------------------------------------------------- + + ! Used for MPI + INTEGER :: ENTCOMM, ENT_RANK + + Contains +!======================================================================== + + Subroutine Init_Entaglement_replicas(Group_Comm) +#ifdef MPI + Use mpi +#endif + Implicit none + Integer, INTENT(IN) :: Group_Comm + + Integer :: ISIZE, IRANK, IERR +#ifdef MPI + ! Create subgroups of two replicas each + CALL MPI_COMM_SIZE(Group_Comm,ISIZE,IERR) + CALL MPI_COMM_RANK(Group_Comm,IRANK,IERR) + CALL MPI_COMM_SPLIT(Group_Comm, IRANK / 2, IRANK, ENTCOMM, IERR) + ENT_RANK = IRANK / 2 +#endif + + end Subroutine Init_Entaglement_replicas + +!======================================================================== + ! Calculation of the Renyi entanglement entropy + ! The algorithm works only for an MPI program + ! We partition the nodes into groups of 2 replicas: + ! (n, n+1), with n=0,2,... + Subroutine Calc_Mutual_Inf(GRC,Phase,Ntau,List_c,Nsites_c,List_f,Nsites_f,Renyi_c,Renyi_f,Renyi_cf) + + Implicit none + + Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (Kind=8), Intent(IN) :: PHASE + Integer, INTENT(IN) :: Ntau + Integer, Dimension(:), INTENT(IN) :: List_c, List_f + Integer, INTENT(IN) :: Nsites_c ,Nsites_f + Complex (Kind=8), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf + + Integer, Dimension(:), Allocatable :: List_cf + Integer :: I, J, IERR, INFO, Nsites_cf + + Nsites_cf=Nsites_c+Nsites_f + + allocate(List_cf(Nsites_cf)) + + DO I = 1, Nsites_c + List_cf(I) = List_c(I) + END DO + DO I = 1, Nsites_f + List_cf(I+Nsites_c) = List_f(I) + END DO + + Call Calc_Renyi(GRC,Phase,Ntau,List_c,Nsites_c,Renyi_c) + Call Calc_Renyi(GRC,Phase,Ntau,List_f,Nsites_f,Renyi_f) + Call Calc_Renyi(GRC,Phase,Ntau,List_cf,Nsites_cf,Renyi_cf) + + deallocate(List_cf) + + End Subroutine Calc_Mutual_Inf + + + Subroutine Calc_Renyi(GRC,Phase,Ntau,List,Nsites,Renyi) +#ifdef MPI + Use mpi +#endif + + Implicit none + + Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (Kind=8), Intent(IN) :: PHASE + Integer, INTENT(IN) :: Ntau + Integer, Dimension(:), INTENT(IN) :: List + Integer, INTENT(IN) :: Nsites + Complex (Kind=8), INTENT(OUT) :: Renyi + + Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Integer, Dimension(:), Allocatable :: PIVOT + Complex (Kind=8) :: DET, PRODDET + Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half + + EXTERNAL ZGEMM + EXTERNAL ZGETRF + + N_FL = size(GRC,3) + N_FL_half = N_FL/2 + + Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + +#ifdef MPI + + + Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) + + DO nf=1,N_FL_half + ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! and GreenA_f_tmp (f electrons) + ! The first Nsites columns contains the spin up sector, + ! the last Nsites column the spin down sector + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J) = GRC(List(I), List(J), 2*nf-1) + END DO + END DO + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J+Nsites) = GRC(List(I), List(J), 2*nf) + END DO + END DO + ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! such that GreenA contains the reduced Green's function for two replicas + ! and a fixed spin sector. + CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + + ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) + DO I = 1, Nsites + IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + END DO + CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, CMPLX(2.D0,0.D0,KIND(0.D0)), GreenA(1:Nsites, 1:Nsites), & + & Nsites, GreenA(1:Nsites, Nsites+1:2*Nsites), Nsites, CMPLX(1.D0,0.D0,KIND(0.D0)), IDA, Nsites) + ! Compute determinant + SELECT CASE(Nsites) + CASE (1) + DET = IDA(1,1) + CASE (2) + DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + CASE DEFAULT + Allocate(PIVOT(Nsites)) + CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) + DET = cmplx(1.D0,0.D0,KIND(0.D0)) + DO I = 1, Nsites + IF (PIVOT(I).NE.I) THEN + DET = -DET * IDA(I,I) + ELSE + DET = DET * IDA(I,I) + END IF + ENDDO + Deallocate(PIVOT) + END SELECT + ! Compute the product of determinants for up and down spin sectors. + CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! Now each thread contains in PRODDET the full determinant, as obtained by + ! a pair of replicas. + Renyi = Renyi * PRODDET + + Enddo + + if (N_FL/=2*N_FL_half) then + + ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! and GreenA_f_tmp (f electrons) + ! The first Nsites columns contains the last flavour sector, + ! the last Nsites column are old (Nf>2) or random, but they won't be used + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J) = GRC(List(I), List(J), N_FL) + END DO + END DO + + ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! such that GreenA contains the reduced Green's function for two replicas + ! and a fixed spin sector. + CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + + if(ENT_RANK==0) then + + ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) + DO I = 1, Nsites + IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + END DO + CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, CMPLX(2.D0,0.D0,KIND(0.D0)), GreenA(1:Nsites, 1:Nsites), & + & Nsites, GreenA(1:Nsites, Nsites+1:2*Nsites), Nsites, CMPLX(1.D0,0.D0,KIND(0.D0)), IDA, Nsites) + ! Compute determinant + SELECT CASE(Nsites) + CASE (1) + DET = IDA(1,1) + CASE (2) + DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + CASE DEFAULT + Allocate(PIVOT(Nsites)) + CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) + DET = cmplx(1.D0,0.D0,KIND(0.D0)) + DO I = 1, Nsites + IF (PIVOT(I).NE.I) THEN + DET = -DET * IDA(I,I) + ELSE + DET = DET * IDA(I,I) + END IF + ENDDO + Deallocate(PIVOT) + END SELECT + + Renyi = Renyi * DET + endif + + endif + + Deallocate(GreenA,GreenA_tmp,IDA) +#endif + + End Subroutine Calc_Renyi + + end Module entanglement \ No newline at end of file -- GitLab From fbf877f7e11cb526076ec1fa9d07df13b0816265 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Uni-PC)" Date: Thu, 19 Apr 2018 13:49:09 +0200 Subject: [PATCH 02/50] Fix Pipeline --- Libraries/Modules/Compile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Modules/Compile b/Libraries/Modules/Compile index 49f26f6f..7aca0f9d 100644 --- a/Libraries/Modules/Compile +++ b/Libraries/Modules/Compile @@ -7,10 +7,10 @@ $(LIB): $(OBJS) ar -r $(LIB) $(OBJS) %.o: %.f90 - $(FC) $(FLAGS) -c -cpp $< + $(FC) $(FLAGS) -c $(F90USEFULFLAGS) $< %.o: %.F90 - $(FC) $(FLAGS) -c -cpp $< + $(FC) $(FLAGS) -c $(F90USEFULFLAGS) $< errors.o: mat_mod.o -- GitLab From 8a1765147880edf34da1e3ba1139c228f99035cb Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Uni-PC)" Date: Thu, 19 Apr 2018 13:52:17 +0200 Subject: [PATCH 03/50] renaming one function --- Libraries/Modules/entanglement.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Libraries/Modules/entanglement.f90 b/Libraries/Modules/entanglement.f90 index ee2fd543..afcac532 100644 --- a/Libraries/Modules/entanglement.f90 +++ b/Libraries/Modules/entanglement.f90 @@ -94,16 +94,16 @@ List_cf(I+Nsites_c) = List_f(I) END DO - Call Calc_Renyi(GRC,Phase,Ntau,List_c,Nsites_c,Renyi_c) - Call Calc_Renyi(GRC,Phase,Ntau,List_f,Nsites_f,Renyi_f) - Call Calc_Renyi(GRC,Phase,Ntau,List_cf,Nsites_cf,Renyi_cf) + Call Calc_Renyi_Ent(GRC,Phase,Ntau,List_c,Nsites_c,Renyi_c) + Call Calc_Renyi_Ent(GRC,Phase,Ntau,List_f,Nsites_f,Renyi_f) + Call Calc_Renyi_Ent(GRC,Phase,Ntau,List_cf,Nsites_cf,Renyi_cf) deallocate(List_cf) End Subroutine Calc_Mutual_Inf - Subroutine Calc_Renyi(GRC,Phase,Ntau,List,Nsites,Renyi) + Subroutine Calc_Renyi_Ent(GRC,Phase,Ntau,List,Nsites,Renyi) #ifdef MPI Use mpi #endif @@ -243,6 +243,6 @@ Deallocate(GreenA,GreenA_tmp,IDA) #endif - End Subroutine Calc_Renyi + End Subroutine Calc_Renyi_Ent end Module entanglement \ No newline at end of file -- GitLab From 532a17de6da755d33f479c7753ccabd5bdd724a6 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Uni-PC)" Date: Thu, 19 Apr 2018 16:37:22 +0200 Subject: [PATCH 04/50] Fix bug --- Libraries/Modules/entanglement.f90 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Libraries/Modules/entanglement.f90 b/Libraries/Modules/entanglement.f90 index afcac532..9509384b 100644 --- a/Libraries/Modules/entanglement.f90 +++ b/Libraries/Modules/entanglement.f90 @@ -59,7 +59,7 @@ CALL MPI_COMM_SIZE(Group_Comm,ISIZE,IERR) CALL MPI_COMM_RANK(Group_Comm,IRANK,IERR) CALL MPI_COMM_SPLIT(Group_Comm, IRANK / 2, IRANK, ENTCOMM, IERR) - ENT_RANK = IRANK / 2 + CALL MPI_COMM_RANK(ENTCOMM,ENT_RANK,IERR) #endif end Subroutine Init_Entaglement_replicas @@ -206,6 +206,7 @@ ! and a fixed spin sector. CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + DET = cmplx(1.D0,0.D0,KIND(0.D0)) if(ENT_RANK==0) then ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) @@ -224,7 +225,6 @@ CASE DEFAULT Allocate(PIVOT(Nsites)) CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) - DET = cmplx(1.D0,0.D0,KIND(0.D0)) DO I = 1, Nsites IF (PIVOT(I).NE.I) THEN DET = -DET * IDA(I,I) @@ -234,9 +234,14 @@ ENDDO Deallocate(PIVOT) END SELECT - - Renyi = Renyi * DET endif + + ! Compute the product of determinants for up and down spin sectors. + CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! Now each thread contains in PRODDET the full determinant, as obtained by + ! a pair of replicas. + + Renyi = Renyi * PRODDET endif -- GitLab From 71a1242da13eaf32e6269aeb115da31f91b63b04 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Uni-PC)" Date: Fri, 20 Apr 2018 15:38:45 +0200 Subject: [PATCH 05/50] the entaglement should now take care of odd number of tasks such that not all task can be paired for replicas --- Libraries/Modules/entanglement.f90 | 180 ++++++++++++++++------------- 1 file changed, 98 insertions(+), 82 deletions(-) diff --git a/Libraries/Modules/entanglement.f90 b/Libraries/Modules/entanglement.f90 index 9509384b..e582820a 100644 --- a/Libraries/Modules/entanglement.f90 +++ b/Libraries/Modules/entanglement.f90 @@ -41,7 +41,7 @@ !-------------------------------------------------------------------- ! Used for MPI - INTEGER :: ENTCOMM, ENT_RANK + INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group Contains !======================================================================== @@ -60,6 +60,10 @@ CALL MPI_COMM_RANK(Group_Comm,IRANK,IERR) CALL MPI_COMM_SPLIT(Group_Comm, IRANK / 2, IRANK, ENTCOMM, IERR) CALL MPI_COMM_RANK(ENTCOMM,ENT_RANK,IERR) + CALL MPI_COMM_SIZE(ENTCOMM,ENT_SIZE,IERR) + Norm=ISIZE/2 ! number of pairs + norm=2*norm ! but each task of pair contributes + group=Group_Comm #endif end Subroutine Init_Entaglement_replicas @@ -131,83 +135,30 @@ Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) #ifdef MPI - + ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated + if(ENT_SIZE==2) then - Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) + Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) - DO nf=1,N_FL_half - ! We store the reduced Green's function in GreenA_c_tmp (c electrons) - ! and GreenA_f_tmp (f electrons) - ! The first Nsites columns contains the spin up sector, - ! the last Nsites column the spin down sector - DO J = 1, Nsites - DO I = 1, Nsites - GreenA_tmp(I,J) = GRC(List(I), List(J), 2*nf-1) - END DO - END DO - DO J = 1, Nsites - DO I = 1, Nsites - GreenA_tmp(I,J+Nsites) = GRC(List(I), List(J), 2*nf) + DO nf=1,N_FL_half + ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! and GreenA_f_tmp (f electrons) + ! The first Nsites columns contains the spin up sector, + ! the last Nsites column the spin down sector + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J) = GRC(List(I), List(J), 2*nf-1) + END DO END DO - END DO - ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas - ! such that GreenA contains the reduced Green's function for two replicas - ! and a fixed spin sector. - CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) - - ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) - IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) - DO I = 1, Nsites - IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) - END DO - CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, CMPLX(2.D0,0.D0,KIND(0.D0)), GreenA(1:Nsites, 1:Nsites), & - & Nsites, GreenA(1:Nsites, Nsites+1:2*Nsites), Nsites, CMPLX(1.D0,0.D0,KIND(0.D0)), IDA, Nsites) - ! Compute determinant - SELECT CASE(Nsites) - CASE (1) - DET = IDA(1,1) - CASE (2) - DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) - CASE DEFAULT - Allocate(PIVOT(Nsites)) - CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) - DET = cmplx(1.D0,0.D0,KIND(0.D0)) - DO I = 1, Nsites - IF (PIVOT(I).NE.I) THEN - DET = -DET * IDA(I,I) - ELSE - DET = DET * IDA(I,I) - END IF - ENDDO - Deallocate(PIVOT) - END SELECT - ! Compute the product of determinants for up and down spin sectors. - CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) - ! Now each thread contains in PRODDET the full determinant, as obtained by - ! a pair of replicas. - Renyi = Renyi * PRODDET - - Enddo - - if (N_FL/=2*N_FL_half) then - - ! We store the reduced Green's function in GreenA_c_tmp (c electrons) - ! and GreenA_f_tmp (f electrons) - ! The first Nsites columns contains the last flavour sector, - ! the last Nsites column are old (Nf>2) or random, but they won't be used - DO J = 1, Nsites - DO I = 1, Nsites - GreenA_tmp(I,J) = GRC(List(I), List(J), N_FL) + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J+Nsites) = GRC(List(I), List(J), 2*nf) + END DO END DO - END DO - - ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas - ! such that GreenA contains the reduced Green's function for two replicas - ! and a fixed spin sector. - CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) - - DET = cmplx(1.D0,0.D0,KIND(0.D0)) - if(ENT_RANK==0) then + ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! such that GreenA contains the reduced Green's function for two replicas + ! and a fixed spin sector. + CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) @@ -225,6 +176,7 @@ CASE DEFAULT Allocate(PIVOT(Nsites)) CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) + DET = cmplx(1.D0,0.D0,KIND(0.D0)) DO I = 1, Nsites IF (PIVOT(I).NE.I) THEN DET = -DET * IDA(I,I) @@ -234,18 +186,82 @@ ENDDO Deallocate(PIVOT) END SELECT - endif + ! Compute the product of determinants for up and down spin sectors. + CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! Now each thread contains in PRODDET the full determinant, as obtained by + ! a pair of replicas. + Renyi = Renyi * PRODDET + + Enddo - ! Compute the product of determinants for up and down spin sectors. - CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) - ! Now each thread contains in PRODDET the full determinant, as obtained by - ! a pair of replicas. + if (N_FL/=2*N_FL_half) then - Renyi = Renyi * PRODDET - + ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! and GreenA_f_tmp (f electrons) + ! The first Nsites columns contains the last flavour sector, + ! the last Nsites column are old (Nf>2) or random, but they won't be used + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J) = GRC(List(I), List(J), N_FL) + END DO + END DO + + ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! such that GreenA contains the reduced Green's function for two replicas + ! and a fixed spin sector. + CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + + DET = cmplx(1.D0,0.D0,KIND(0.D0)) + if(ENT_RANK==0) then + + ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) + DO I = 1, Nsites + IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + END DO + CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, CMPLX(2.D0,0.D0,KIND(0.D0)), GreenA(1:Nsites, 1:Nsites), & + & Nsites, GreenA(1:Nsites, Nsites+1:2*Nsites), Nsites, CMPLX(1.D0,0.D0,KIND(0.D0)), IDA, Nsites) + ! Compute determinant + SELECT CASE(Nsites) + CASE (1) + DET = IDA(1,1) + CASE (2) + DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + CASE DEFAULT + Allocate(PIVOT(Nsites)) + CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) + DO I = 1, Nsites + IF (PIVOT(I).NE.I) THEN + DET = -DET * IDA(I,I) + ELSE + DET = DET * IDA(I,I) + END IF + ENDDO + Deallocate(PIVOT) + END SELECT + endif + + ! Compute the product of determinants for up and down spin sectors. + CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! Now each thread contains in PRODDET the full determinant, as obtained by + ! a pair of replicas. + + Renyi = Renyi * PRODDET + + endif + + Deallocate(GreenA,GreenA_tmp,IDA) + + else + ! if there had been an odd number of task in tempering group / world, set renyi to 0 + Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) endif - Deallocate(GreenA,GreenA_tmp,IDA) + ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call + CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) + Renyi=PRODDET/dble(norm) + ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. + ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif End Subroutine Calc_Renyi_Ent -- GitLab From 30a2b4e70b57519efb3352df31349eaebd7b5f04 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Thu, 17 Sep 2020 16:29:26 +0300 Subject: [PATCH 06/50] entanglement --- Libraries/Modules/Makefile | 4 ++-- .../Modules/{entanglement.f90 => entanglement_mod.F90} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename Libraries/Modules/{entanglement.f90 => entanglement_mod.F90} (98%) diff --git a/Libraries/Modules/Makefile b/Libraries/Modules/Makefile index dd85352c..f6a732b4 100644 --- a/Libraries/Modules/Makefile +++ b/Libraries/Modules/Makefile @@ -1,10 +1,10 @@ LIB=modules_90.a OBJS=errors_mod.o files_mod.o fourier_mod.o histograms_mod.o histograms_v2_mod.o lattices_v3_mod.o \ log_mesh_mod.o mymats_mod.o matrix_mod.o maxent_mod.o maxent_stoch_mod.o \ - natural_constants_mod.o precdef_mod.o random_wrap_mod.o Mat_subroutines.o + natural_constants_mod.o precdef_mod.o random_wrap_mod.o Mat_subroutines.o entanglement_mod.o MODS=errors.mod files_mod.mod fourier.mod histograms.mod histograms_v2.mod lattices_v3.mod \ log_mesh.mod mymats.mod matrix.mod maxent_mod.mod maxent_stoch_mod.mod \ - natural_constants.mod precdef.mod random_wrap.mod + natural_constants.mod precdef.mod random_wrap.mod entanglement_mod.mod $(LIB): $(OBJS) ar -r $(LIB) $(OBJS) diff --git a/Libraries/Modules/entanglement.f90 b/Libraries/Modules/entanglement_mod.F90 similarity index 98% rename from Libraries/Modules/entanglement.f90 rename to Libraries/Modules/entanglement_mod.F90 index e582820a..05f32d86 100644 --- a/Libraries/Modules/entanglement.f90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -46,7 +46,7 @@ Contains !======================================================================== - Subroutine Init_Entaglement_replicas(Group_Comm) + Subroutine Init_Entanglement_replicas(Group_Comm) #ifdef MPI Use mpi #endif @@ -66,7 +66,7 @@ group=Group_Comm #endif - end Subroutine Init_Entaglement_replicas + end Subroutine Init_Entanglement_replicas !======================================================================== ! Calculation of the Renyi entanglement entropy @@ -266,4 +266,4 @@ End Subroutine Calc_Renyi_Ent - end Module entanglement \ No newline at end of file + end Module entanglement -- GitLab From 1826a8121d7ff9575f01c35b21babc3eb43742cf Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Fri, 18 Sep 2020 23:03:50 +0300 Subject: [PATCH 07/50] add analysis tool for entanglement entropy --- Analysis/Makefile | 4 +- Analysis/cov_mut.F90 | 188 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 Analysis/cov_mut.F90 diff --git a/Analysis/Makefile b/Analysis/Makefile index bb014a93..0f7889a2 100644 --- a/Analysis/Makefile +++ b/Analysis/Makefile @@ -1,6 +1,6 @@ .PHONY : all tidy clean -BINS= cov_scal.out cov_tau.out cov_tau_ph.out Max_SAC.out cov_eq.out -OBJS= cov_scal.o cov_tau.o cov_tau_ph.o Max_SAC.o cov_eq.o +BINS= cov_scal.out cov_tau.out cov_tau_ph.out Max_SAC.out cov_eq.out cov_mut.out +OBJS= cov_scal.o cov_tau.o cov_tau_ph.o Max_SAC.o cov_eq.o cov_mut.o OBJS1 = Predefined_Latt_mod.o MODS=predefined_lattices.mod diff --git a/Analysis/cov_mut.F90 b/Analysis/cov_mut.F90 new file mode 100644 index 00000000..6b9d8492 --- /dev/null +++ b/Analysis/cov_mut.F90 @@ -0,0 +1,188 @@ +! Copyright (C) 2016 The ALF project +! +! The ALF project is free software: you can redistribute it and/or modify +! it under the terms of the GNU General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! The ALF project is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU General Public License for more details. +! +! You should have received a copy of the GNU General Public License +! along with Foobar. If not, see http://www.gnu.org/licenses/. +! +! Under Section 7 of GPL version 3 we require you to fulfill the following additional terms: +! +! - It is our hope that this program makes a contribution to the scientific community. Being +! part of that community we feel that it is reasonable to require you to give an attribution +! back to the original authors if you have benefitted from this program. +! Guidelines for a proper citation can be found on the project's homepage +! http://alf.physik.uni-wuerzburg.de . +! +! - We require the preservation of the above copyright notice and this license in all original files. +! +! - We prohibit the misrepresentation of the origin of the original source files. To obtain +! the original source files please visit the homepage http://alf.physik.uni-wuerzburg.de . +! +! - If you make substantial changes to the program we require you to either consider contributing +! to the ALF project or to mark your material in a reasonable way as different from the original version. + + Program Cov_vec + +!-------------------------------------------------------------------- +!> @author +!> ALF-project +! +!> @brief +!> Analysis program for scalar observables +! +!-------------------------------------------------------------------- + + + Use ERRORS + Implicit none + + REAL (Kind=Kind(0.d0)), DIMENSION(:,:), ALLOCATABLE :: OBS + REAL (Kind=Kind(0.d0)), DIMENSION(:), ALLOCATABLE :: EN, SIGN + REAL (Kind=Kind(0.d0)) :: XM, XERR, X + REAL (Kind=Kind(0.d0)), External :: mutinf, entanglement + + ! Complex (Kind=Kind(0.d0)) Z1,Z2,Z3,Z4,Z5 + Complex (Kind=Kind(0.d0)), Allocatable :: Tmp(:) + REAL (Kind=Kind(0.d0)), Allocatable :: AutoCorr(:) + Integer :: Nobs , avmin, avmax, avdiff, avmax2, avdiff2 + Integer :: Nbins, Nbins_eff, I, IOBS, N_Back, nav=2 + Integer :: N,N1 !, NBIN + + Integer :: n_skip, N_rebin, N_Cov, ierr, N_auto + Character (len=64) :: File_out + NAMELIST /VAR_errors/ n_skip, N_rebin, N_Cov, N_Back, N_auto + + + N_auto=0 + OPEN(UNIT=5,FILE='parameters',STATUS='old',ACTION='read',IOSTAT=ierr) + IF (ierr /= 0) THEN + WRITE(*,*) 'unable to open ',ierr + STOP + END IF + READ(5,NML=VAR_errors) + CLOSE(5) + + + ! Count the number of bins + Open (Unit=10, File="Var_scal", status="unknown") + Read(10,*) NOBS + allocate (Tmp(NOBS) ) + rewind(10) + Nbins = 0 + do + read(10,*,End=10) N, (Tmp(I), I=1,size(Tmp,1)-1), X + Tmp(NOBS) = cmplx(X,0.d0,kind(0.d0)) + Nbins = Nbins + 1 + enddo +10 continue + Write(6,*) "# of bins: ", Nbins + Close(10) + + ALLOCATE(OBS(Nbins,NOBS)) + + OPEN (UNIT=20, FILE='Var_scal', STATUS='old') + Nbins_eff = 0 + DO N = 1,Nbins + IF (N > N_skip) THEN + Nbins_eff = Nbins_eff + 1 + READ(20,*) N1, (Tmp(I), I=1,size(Tmp,1)-1),X + Tmp(NOBS) = cmplx(X,0.d0,kind(0.d0)) + OBS(Nbins_eff,:) = dble(Tmp(:)) + ELSE + READ(20,*) N1, (Tmp(I), I=1,size(Tmp,1)-1),X + ENDIF + ENDDO + CLOSE(20) +2100 FORMAT(I6,2X,F16.8) + N_auto=min(N_auto,Nbins_eff-3) + if(Nbins_eff <= 1) then + write (*,*) "Effective # of bins smaller then 2. Analysis impossible!" + stop 1 + endif + + OPEN (UNIT=21, FILE='Var_scalJ', STATUS='unknown') + WRITE(21,*) 'Effective number of bins, and bins: ', Nbins_eff, Nbins + ALLOCATE (EN(Nbins_eff), SIGN(Nbins_eff)) + DO IOBS = 1,NOBS + WRITE(21,*) + DO I = 1,Nbins_eff + EN (I) = Real(OBS(I,IOBS), kind(0.d0)) + SIGN(I) = Real(OBS(I,NOBS), kind(0.d0)) + ENDDO + IF (IOBS.EQ.NOBS ) then + CALL ERRCALCJ(EN, XM,XERR,N_Rebin) + else + CALL ERRCALCJ(Obs(1:Nbins_eff,Iobs:Iobs),SIGN,XM,XERR,N_Rebin,entanglement) + endif + WRITE(21,2001) IOBS, XM, XERR + ENDDO + If (Nobs==4) then + write(*,*) "you should not be here" + WRITE(21,*) + CALL ERRCALCJ(Obs(1:Nbins_eff,:),SIGN,XM,XERR,N_Rebin,mutinf) + WRITE(21,2001) IOBS, XM, XERR + endif + CLOSE(21) +2001 FORMAT('OBS : ', I4,4x,E16.6,2X, E16.6) + + if(N_auto>0) then + ALLOCATE(AutoCorr(N_auto)) + DO IOBS = 1,NOBS-1 + write(File_out,'("Var_scal_Auto_",I1.1)') iobs + write(*,*) File_out + OPEN (UNIT=21, FILE=File_out, STATUS='unknown') + WRITE(21,*) + DO I = 1,Nbins_eff + EN (I) = Real(OBS(I,IOBS), kind(0.d0)) + ENDDO + Call AUTO_COR(EN,AutoCorr) + do i = 1,N_auto + avmin=max(1,i-nav) + avmax=min(Nbins_eff,i+nav) + avmax2=min(N_auto,i+nav) + avdiff= avmax-avmin+1 + avdiff2= avmax2-avmin+1 + CALL ERRCALCJ(EN,XM,XERR,i) + write(21,*) i, sum(AutoCorr(avmin:avmax2))/dble(avdiff2), Xerr, En(i), sum(En(avmin:avmax))/dble(avdiff) + enddo + do i = N_auto+1,Nbins_eff + avmin=max(1,i-nav) + avmax=min(Nbins_eff,i+nav) + avdiff= avmax-avmin+1 + write(21,*) i, 0.d0, 0.d0, En(i), sum(En(avmin:avmax))/dble(avdiff) + enddo + CLOSE(21) + ENDDO + endif + + DEALLOCATE (EN,SIGN,OBS) + + END Program Cov_vec + + + REAL (Kind=Kind(0.d0)) function mutinf(X) + + Implicit None + REAL (Kind=Kind(0.d0)) :: X(3) + + mutinf = log(X(3)/(X(1)*X(2))) + + end function mutinf + + + REAL (Kind=Kind(0.d0)) function entanglement(X) + + Implicit None + REAL (Kind=Kind(0.d0)) :: X(1) + + entanglement = -log(X(1)) + + end function entanglement -- GitLab From 39d93db8adc80fd8df62b17ec1dfc99276c02a82 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Fri, 18 Sep 2020 23:05:04 +0300 Subject: [PATCH 08/50] improved zgemm calls for entanglement module --- Libraries/Modules/entanglement_mod.F90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 05f32d86..df7954e0 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -123,7 +123,7 @@ Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA Integer, Dimension(:), Allocatable :: PIVOT - Complex (Kind=8) :: DET, PRODDET + Complex (Kind=8) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half EXTERNAL ZGEMM @@ -133,6 +133,8 @@ N_FL_half = N_FL/2 Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + alpha=CMPLX(2.d0,0.d0,kind(0.d0)) + beta =CMPLX(1.d0,0.d0,kind(0.d0)) #ifdef MPI ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated @@ -165,8 +167,8 @@ DO I = 1, Nsites IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) END DO - CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, CMPLX(2.D0,0.D0,KIND(0.D0)), GreenA(1:Nsites, 1:Nsites), & - & Nsites, GreenA(1:Nsites, Nsites+1:2*Nsites), Nsites, CMPLX(1.D0,0.D0,KIND(0.D0)), IDA, Nsites) + CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, alpha, GreenA(1, 1), & + & Nsites, GreenA(1, Nsites+1), Nsites, beta, IDA, Nsites) ! Compute determinant SELECT CASE(Nsites) CASE (1) @@ -219,8 +221,8 @@ DO I = 1, Nsites IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) END DO - CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, CMPLX(2.D0,0.D0,KIND(0.D0)), GreenA(1:Nsites, 1:Nsites), & - & Nsites, GreenA(1:Nsites, Nsites+1:2*Nsites), Nsites, CMPLX(1.D0,0.D0,KIND(0.D0)), IDA, Nsites) + CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, alpha, GreenA(1, 1), & + & Nsites, GreenA(1, Nsites+1), Nsites, beta, IDA, Nsites) ! Compute determinant SELECT CASE(Nsites) CASE (1) -- GitLab From 22497f938080370a6e4cf48eb3932a3e53a9eef8 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Fri, 18 Sep 2020 23:06:37 +0300 Subject: [PATCH 09/50] pass MPI config to module compilation stage, required for entanglement module --- configure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.sh b/configure.sh index f7e27995..f8d2d4bc 100755 --- a/configure.sh +++ b/configure.sh @@ -264,7 +264,7 @@ if [ ! -z "${ALF_FLAGS_EXT+x}" ]; then fi ALF_FLAGS_QRREF="${F90OPTFLAGS} ${ALF_FLAGS_EXT}" -ALF_FLAGS_MODULES="${F90OPTFLAGS} ${ALF_FLAGS_EXT}" +ALF_FLAGS_MODULES="${F90OPTFLAGS} ${PROGRAMMCONFIGURATION} ${ALF_FLAGS_EXT}" ALF_FLAGS_ANA="${F90OPTFLAGS} ${ALF_INC} ${ALF_FLAGS_EXT}" ALF_FLAGS_PROG="${F90USEFULFLAGS} ${F90OPTFLAGS} ${PROGRAMMCONFIGURATION} ${ALF_INC} ${ALF_FLAGS_EXT}" export ALF_FLAGS_QRREF -- GitLab From c20cc87ec3c41fca521dc0f4fc09900306b9fbed Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Wed, 4 Nov 2020 12:08:24 -0500 Subject: [PATCH 10/50] it compiles now. --- Libraries/Modules/entanglement_mod.F90 | 465 ++++++++++++++++++------- 1 file changed, 337 insertions(+), 128 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index df7954e0..dd2894f3 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -72,42 +72,40 @@ ! Calculation of the Renyi entanglement entropy ! The algorithm works only for an MPI program ! We partition the nodes into groups of 2 replicas: - ! (n, n+1), with n=0,2,... - Subroutine Calc_Mutual_Inf(GRC,Phase,Ntau,List_c,Nsites_c,List_f,Nsites_f,Renyi_c,Renyi_f,Renyi_cf) + ! ! (n, n+1), with n=0,2,... + ! Subroutine Calc_Mutual_Inf(GRC,List_c,Nsites_c,List_f,Nsites_f,Renyi_c,Renyi_f,Renyi_cf) - Implicit none + ! Implicit none - Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) - Complex (Kind=8), Intent(IN) :: PHASE - Integer, INTENT(IN) :: Ntau - Integer, Dimension(:), INTENT(IN) :: List_c, List_f - Integer, INTENT(IN) :: Nsites_c ,Nsites_f - Complex (Kind=8), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf + ! Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + ! Integer, Dimension(:), INTENT(IN) :: List_c, List_f + ! Integer, INTENT(IN) :: Nsites_c ,Nsites_f + ! Complex (Kind=8), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf - Integer, Dimension(:), Allocatable :: List_cf - Integer :: I, J, IERR, INFO, Nsites_cf + ! Integer, Dimension(:), Allocatable :: List_cf + ! Integer :: I, J, IERR, INFO, Nsites_cf - Nsites_cf=Nsites_c+Nsites_f + ! Nsites_cf=Nsites_c+Nsites_f - allocate(List_cf(Nsites_cf)) + ! allocate(List_cf(Nsites_cf)) - DO I = 1, Nsites_c - List_cf(I) = List_c(I) - END DO - DO I = 1, Nsites_f - List_cf(I+Nsites_c) = List_f(I) - END DO + ! DO I = 1, Nsites_c + ! List_cf(I) = List_c(I) + ! END DO + ! DO I = 1, Nsites_f + ! List_cf(I+Nsites_c) = List_f(I) + ! END DO - Call Calc_Renyi_Ent(GRC,Phase,Ntau,List_c,Nsites_c,Renyi_c) - Call Calc_Renyi_Ent(GRC,Phase,Ntau,List_f,Nsites_f,Renyi_f) - Call Calc_Renyi_Ent(GRC,Phase,Ntau,List_cf,Nsites_cf,Renyi_cf) + ! Call Calc_Renyi_Ent(GRC,List_c,Nsites_c,Renyi_c) + ! Call Calc_Renyi_Ent(GRC,List_f,Nsites_f,Renyi_f) + ! Call Calc_Renyi_Ent(GRC,List_cf,Nsites_cf,Renyi_cf) - deallocate(List_cf) + ! deallocate(List_cf) - End Subroutine Calc_Mutual_Inf + ! End Subroutine Calc_Mutual_Inf - Subroutine Calc_Renyi_Ent(GRC,Phase,Ntau,List,Nsites,Renyi) + Subroutine Calc_Renyi_Ent(GRC,List,Nsites,N_SUN,Renyi) #ifdef MPI Use mpi #endif @@ -115,22 +113,40 @@ Implicit none Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) - Complex (Kind=8), Intent(IN) :: PHASE - Integer, INTENT(IN) :: Ntau - Integer, Dimension(:), INTENT(IN) :: List - Integer, INTENT(IN) :: Nsites + Integer, Dimension(:,:), INTENT(IN) :: List ! new + Integer, INTENT(IN) :: Nsites(:), N_SUN(:) ! new Complex (Kind=8), INTENT(OUT) :: Renyi Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA Integer, Dimension(:), Allocatable :: PIVOT Complex (Kind=8) :: DET, PRODDET, alpha, beta - Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half + Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav + Integer , Dimension(:), Allocatable :: SortedFlavors ! new + Integer , Dimension(:,:), Allocatable :: List_tmp + Integer , Dimension(2) :: Nsites_tmp,nf_list,N_SUN_tmp EXTERNAL ZGEMM EXTERNAL ZGETRF N_FL = size(GRC,3) - N_FL_half = N_FL/2 + + Allocate(SortedFlavors(N_FL)) ! new + + ! insertion sort for small number of elements, SortedFlavors lists flavors in order of size + start_flav=0 + if (Nsites(1)==0) start_flav = 1 + DO I=2,N_FL + x = Nsites(I) + if (Nsites(1)==0) start_flav = start_flav + 1 + J = I-1 + DO while(J >= 1) + if(Nsites(J) <= x) exit + SortedFlavors(J+1) = J + J = J - 1 + end do + SortedFlavors(J+1) = I + END DO + N_FL_half = (N_FL-start_flav)/2 Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) @@ -140,115 +156,150 @@ ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated if(ENT_SIZE==2) then - Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) + !Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) + dim = Nsites(SortedFlavors(N_FL)) ! new + allocate(List_tmp(dim,2)) + Allocate(GreenA(dim,2*dim),GreenA_tmp(dim,2*dim),IDA(dim,dim)) ! new DO nf=1,N_FL_half - ! We store the reduced Green's function in GreenA_c_tmp (c electrons) - ! and GreenA_f_tmp (f electrons) - ! The first Nsites columns contains the spin up sector, - ! the last Nsites column the spin down sector - DO J = 1, Nsites - DO I = 1, Nsites - GreenA_tmp(I,J) = GRC(List(I), List(J), 2*nf-1) - END DO - END DO - DO J = 1, Nsites - DO I = 1, Nsites - GreenA_tmp(I,J+Nsites) = GRC(List(I), List(J), 2*nf) - END DO - END DO - ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas - ! such that GreenA contains the reduced Green's function for two replicas - ! and a fixed spin sector. - CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + ! ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! ! and GreenA_f_tmp (f electrons) + ! ! The first Nsites columns contains the spin up sector, + ! ! the last Nsites column the spin down sector + ! !DO J = 1, Nsites + ! !DO I = 1, Nsites + ! !GreenA_tmp(I,J) = GRC(List(I), List(J), 2*nf-1) + ! !END DO + ! !END DO + ! nf_eff = SortedFlavors(start_flav+2*nf-1) + + ! DO J = 1, Nsites(nf_eff) + ! Do I = 1, Nsites(nf_eff) + ! GreenA_tmp(I,J) = GRC(List(I,nf_eff),List(J,nf_eff),nf_eff) + ! END DO + ! END Do - ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) - IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) - DO I = 1, Nsites - IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) - END DO - CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, alpha, GreenA(1, 1), & - & Nsites, GreenA(1, Nsites+1), Nsites, beta, IDA, Nsites) - ! Compute determinant - SELECT CASE(Nsites) - CASE (1) - DET = IDA(1,1) - CASE (2) - DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) - CASE DEFAULT - Allocate(PIVOT(Nsites)) - CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) - DET = cmplx(1.D0,0.D0,KIND(0.D0)) - DO I = 1, Nsites - IF (PIVOT(I).NE.I) THEN - DET = -DET * IDA(I,I) - ELSE - DET = DET * IDA(I,I) - END IF - ENDDO - Deallocate(PIVOT) - END SELECT - ! Compute the product of determinants for up and down spin sectors. - CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) - ! Now each thread contains in PRODDET the full determinant, as obtained by - ! a pair of replicas. + ! nf_eff = SortedFlavors(start_flav+2*nf) + ! DO J = 1, Nsites(nf_eff) + ! DO I = 1, Nsites(nf_eff) + ! GreenA_tmp(I,J+dim) = GRC(List(I,nf_eff), List(J,nf_eff), nf_eff) + ! END DO + ! END DO + ! ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! ! such that GreenA contains the reduced Green's function for two replicas + ! ! and a fixed spin sector. + ! ! CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + ! CALL MPI_ALLTOALL(GreenA_tmp, dim**2, MPI_COMPLEX16, GreenA, dim**2, MPI_COMPLEX16, ENTCOMM, IERR) + + ! ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + ! nf_eff = SortedFlavors(start_flav+2*nf - 1 + ENT_RANK) + ! dim_eff = Nsites(nf_eff) + + ! IDA(1:dim_eff,1:dim_eff) = - GreenA(1:dim_eff, 1:dim_eff) - GreenA(1:dim_eff, dim+1:dim+dim_eff) + ! DO I = 1, dim_eff + ! IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + ! END DO + ! CALL ZGEMM('n', 'n', dim_eff, dim_eff, dim_eff, alpha, GreenA(1, 1), & + ! & dim, GreenA(1, dim+1), dim, beta, IDA, dim) + ! ! Compute determinant + ! SELECT CASE(dim_eff) + ! CASE (1) + ! DET = IDA(1,1) + ! CASE (2) + ! DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + ! CASE DEFAULT + ! Allocate(PIVOT(dim_eff)) + ! CALL ZGETRF(dim_eff, dim_eff, IDA, dim, PIVOT, INFO) + ! DET = cmplx(1.D0,0.D0,KIND(0.D0)) + ! DO I = 1, dim_eff + ! IF (PIVOT(I).NE.I) THEN + ! DET = -DET * IDA(I,I) + ! ELSE + ! DET = DET * IDA(I,I) + ! END IF + ! ENDDO + ! Deallocate(PIVOT) + ! END SELECT + ! DET=DET**N_SUN(nf_eff) !! ATTENTION take care of this!!! + ! ! Compute the product of determinants for up and down spin sectors. + ! CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! ! Now each thread contains in PRODDET the full determinant, as obtained by + ! ! a pair of replicas. + + + DO J = 1, 2 + nf_eff = SortedFlavors(start_flav+2*nf-2+J) + Nsites_tmp(J)=Nsites(nf_eff) + List_tmp(:,J)=List(:,nf_eff) + N_sun_tmp(J)=N_SUN(nf_eff) + nf_list(J)=nf_eff + enddo + call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) Renyi = Renyi * PRODDET Enddo - if (N_FL/=2*N_FL_half) then + if (N_FL/=2*N_FL_half+start_flav) then + + nf_eff = SortedFlavors(N_fl) + List_tmp(:,1)=List(:,nf_eff) + + call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf_eff),nf_eff,N_SUN(nf_eff),PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET - ! We store the reduced Green's function in GreenA_c_tmp (c electrons) - ! and GreenA_f_tmp (f electrons) - ! The first Nsites columns contains the last flavour sector, - ! the last Nsites column are old (Nf>2) or random, but they won't be used - DO J = 1, Nsites - DO I = 1, Nsites - GreenA_tmp(I,J) = GRC(List(I), List(J), N_FL) - END DO - END DO + ! ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! ! and GreenA_f_tmp (f electrons) + ! ! The first Nsites columns contains the last flavour sector, + ! ! the last Nsites column are old (Nf>2) or random, but they won't be used + ! nf_eff=SortedFlavors(N_FL) + ! DO J = 1, Nsites + ! DO I = 1, Nsites + ! GreenA_tmp(I,J) = GRC(List(I,nf_eff), List(J,nf_eff), nf_eff) + ! END DO + ! END DO - ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas - ! such that GreenA contains the reduced Green's function for two replicas - ! and a fixed spin sector. - CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) + ! ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! ! such that GreenA contains the reduced Green's function for two replicas + ! ! and a fixed spin sector. + ! CALL MPI_ALLTOALL(GreenA_tmp, dim**2, MPI_COMPLEX16, GreenA, dim**2, MPI_COMPLEX16, ENTCOMM, IERR) - DET = cmplx(1.D0,0.D0,KIND(0.D0)) - if(ENT_RANK==0) then + ! DET = cmplx(1.D0,0.D0,KIND(0.D0)) + ! if(ENT_RANK==0) then - ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) - IDA = - GreenA(1:Nsites, 1:Nsites) - GreenA(1:Nsites, Nsites+1:2*Nsites) - DO I = 1, Nsites - IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) - END DO - CALL ZGEMM('n', 'n', Nsites, Nsites, Nsites, alpha, GreenA(1, 1), & - & Nsites, GreenA(1, Nsites+1), Nsites, beta, IDA, Nsites) - ! Compute determinant - SELECT CASE(Nsites) - CASE (1) - DET = IDA(1,1) - CASE (2) - DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) - CASE DEFAULT - Allocate(PIVOT(Nsites)) - CALL ZGETRF(Nsites, Nsites, IDA, Nsites, PIVOT, INFO) - DO I = 1, Nsites - IF (PIVOT(I).NE.I) THEN - DET = -DET * IDA(I,I) - ELSE - DET = DET * IDA(I,I) - END IF - ENDDO - Deallocate(PIVOT) - END SELECT - endif - - ! Compute the product of determinants for up and down spin sectors. - CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) - ! Now each thread contains in PRODDET the full determinant, as obtained by - ! a pair of replicas. + ! ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + ! IDA = - GreenA(1:dim, 1:dim) - GreenA(1:dim, dim+1:2*dim) + ! DO I = 1, dim + ! IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + ! END DO + ! CALL ZGEMM('n', 'n', dim, dim, dim, alpha, GreenA(1, 1), & + ! & dim, GreenA(1, dim+1), dim, beta, IDA, dim) + ! ! Compute determinant + ! SELECT CASE(dim) + ! CASE (1) + ! DET = IDA(1,1) + ! CASE (2) + ! DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + ! CASE DEFAULT + ! Allocate(PIVOT(dim)) + ! CALL ZGETRF(dim, dim, IDA, dim, PIVOT, INFO) + ! DO I = 1, dim + ! IF (PIVOT(I).NE.I) THEN + ! DET = -DET * IDA(I,I) + ! ELSE + ! DET = DET * IDA(I,I) + ! END IF + ! ENDDO + ! Deallocate(PIVOT) + ! END SELECT + ! Det=Det**N_SUN(nf_eff) + ! endif - Renyi = Renyi * PRODDET + ! ! Compute the product of determinants for up and down spin sectors. + ! CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! ! Now each thread contains in PRODDET the full determinant, as obtained by + ! ! a pair of replicas. + + ! Renyi = Renyi * PRODDET endif @@ -268,4 +319,162 @@ End Subroutine Calc_Renyi_Ent +#ifdef MPI + subroutine Calc_Renyi_Ent_pair(GRC,List,Nsites,nf_list,N_SUN,Renyi,GreenA, GreenA_tmp, IDA) + Use mpi + + Implicit none + + Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Integer, Dimension(:,:), INTENT(IN) :: List ! new + Integer, INTENT(IN) :: Nsites(2), N_SUN(2),nf_list(2) ! new + Complex (Kind=8), INTENT(OUT), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (Kind=8), INTENT(OUT) :: Renyi + + Integer, Dimension(:), Allocatable :: PIVOT + Complex (Kind=8) :: DET, PRODDET, alpha, beta + Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav + Integer , Dimension(:), Allocatable :: SortedFlavors ! new + + + Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + alpha=CMPLX(2.d0,0.d0,kind(0.d0)) + beta =CMPLX(1.d0,0.d0,kind(0.d0)) + + dim=size(IDA,1) + ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! and GreenA_f_tmp (f electrons) + ! The first Nsites columns contains the spin up sector, + ! the last Nsites column the spin down sector + nf_eff = nf_list(1) + + DO J = 1, Nsites(1) + Do I = 1, Nsites(1) + GreenA_tmp(I,J) = GRC(List(I,1),List(J,1),nf_eff) + END DO + END Do + + nf_eff = nf_list(2) + DO J = 1, Nsites(2) + DO I = 1, Nsites(2) + GreenA_tmp(I,J+dim) = GRC(List(I,2), List(J,2), nf_eff) + END DO + END DO + ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! such that GreenA contains the reduced Green's function for two replicas + ! and a fixed spin sector. + CALL MPI_ALLTOALL(GreenA_tmp, dim**2, MPI_COMPLEX16, GreenA, dim**2, MPI_COMPLEX16, ENTCOMM, IERR) + + ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + dim_eff = Nsites(1+ENT_RANK) + IDA(1:dim_eff,1:dim_eff) = - GreenA(1:dim_eff, 1:dim_eff) - GreenA(1:dim_eff, dim+1:dim+dim_eff) + DO I = 1, dim_eff + IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + END DO + CALL ZGEMM('n', 'n', dim_eff, dim_eff, dim_eff, alpha, GreenA(1, 1), & + & dim, GreenA(1, dim+1), dim, beta, IDA, dim) + ! Compute determinant + SELECT CASE(dim_eff) + CASE (1) + DET = IDA(1,1) + CASE (2) + DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + CASE DEFAULT + Allocate(PIVOT(dim_eff)) + CALL ZGETRF(dim_eff, dim_eff, IDA, dim, PIVOT, INFO) + DET = cmplx(1.D0,0.D0,KIND(0.D0)) + DO I = 1, dim_eff + IF (PIVOT(I).NE.I) THEN + DET = -DET * IDA(I,I) + ELSE + DET = DET * IDA(I,I) + END IF + ENDDO + Deallocate(PIVOT) + END SELECT + DET=DET**N_SUN(1+ENT_RANK) !! ATTENTION take care of this!!! + ! Compute the product of determinants for up and down spin sectors. + CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! Now each thread contains in PRODDET the full determinant, as obtained by + ! a pair of replicas. + Renyi = Renyi * PRODDET + end subroutine Calc_Renyi_Ent_pair + + subroutine Calc_Renyi_Ent_single(GRC,List,Nsites,nf_eff,N_SUN,Renyi,GreenA, GreenA_tmp, IDA) + Use mpi + + Implicit none + + Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Integer, Dimension(:), INTENT(IN) :: List ! new + Integer, INTENT(IN) :: Nsites, N_SUN,nf_eff ! new + Complex (Kind=8), INTENT(OUT), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (Kind=8), INTENT(OUT) :: Renyi + + Integer, Dimension(:), Allocatable :: PIVOT + Complex (Kind=8) :: DET, PRODDET, alpha, beta + Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, start_flav + Integer , Dimension(:), Allocatable :: SortedFlavors ! new + + + Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + alpha=CMPLX(2.d0,0.d0,kind(0.d0)) + beta =CMPLX(1.d0,0.d0,kind(0.d0)) + + dim=size(IDA,1) + ! We store the reduced Green's function in GreenA_c_tmp (c electrons) + ! and GreenA_f_tmp (f electrons) + ! The first Nsites columns contains the last flavour sector, + ! the last Nsites column are old (Nf>2) or random, but they won't be used + + DO J = 1, Nsites + DO I = 1, Nsites + GreenA_tmp(I,J) = GRC(List(I), List(J), nf_eff) + END DO + END DO + + ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas + ! such that GreenA contains the reduced Green's function for two replicas + ! and a fixed spin sector. + CALL MPI_ALLTOALL(GreenA_tmp, dim**2, MPI_COMPLEX16, GreenA, dim**2, MPI_COMPLEX16, ENTCOMM, IERR) + + DET = cmplx(1.D0,0.D0,KIND(0.D0)) + if(ENT_RANK==0) then + dim_eff = NSites + ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) + IDA = - GreenA(1:dim_eff, 1:dim_eff) - GreenA(1:dim_eff, dim+1:dim+dim_eff) + DO I = 1, dim_eff + IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) + END DO + CALL ZGEMM('n', 'n', dim_eff, dim_eff, dim_eff, alpha, GreenA(1, 1), & + & dim, GreenA(1, dim+1), dim, beta, IDA, dim) + ! Compute determinant + SELECT CASE(dim_eff) + CASE (1) + DET = IDA(1,1) + CASE (2) + DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) + CASE DEFAULT + Allocate(PIVOT(dim_eff)) + CALL ZGETRF(dim_eff, dim_eff, IDA, dim, PIVOT, INFO) + DO I = 1, dim_eff + IF (PIVOT(I).NE.I) THEN + DET = -DET * IDA(I,I) + ELSE + DET = DET * IDA(I,I) + END IF + ENDDO + Deallocate(PIVOT) + END SELECT + Det=Det**N_SUN + endif + + ! Compute the product of determinants for up and down spin sectors. + CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) + ! Now each thread contains in PRODDET the full determinant, as obtained by + ! a pair of replicas. + Renyi = Renyi * PRODDET + end subroutine Calc_Renyi_Ent_single +#endif + end Module entanglement -- GitLab From 7ab98bc5d80bd59b5d6527fb34ddfc677de8b7c5 Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Wed, 4 Nov 2020 20:22:53 -0500 Subject: [PATCH 11/50] added two more renyi functions and inteface. compiles. --- Libraries/Modules/entanglement_mod.F90 | 315 +++++++++++++++---------- 1 file changed, 191 insertions(+), 124 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index dd2894f3..5ceda8a8 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -30,6 +30,20 @@ ! to the ALF project or to mark your material in a reasonable way as different from the original version. Module entanglement + INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + + INTERFACE Calc_Renyi_Ent + MODULE PROCEDURE Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl, Calc_Renyi_Ent_gen_all + END INTERFACE + INTERFACE Init_Entanglement_replicas + MODULE PROCEDURE Init_Entanglement_replicas + END INTERFACE + ! INTERFACE Calc_Mutual_Inf + ! MODULE PROCEDURE Calc_Mutual_Inf + ! END INTERFACE + Contains + +!-------------------------------------------------------------------- !-------------------------------------------------------------------- !> @author @@ -41,9 +55,9 @@ !-------------------------------------------------------------------- ! Used for MPI - INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + ! INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group - Contains + ! Contains !======================================================================== Subroutine Init_Entanglement_replicas(Group_Comm) @@ -103,9 +117,81 @@ ! deallocate(List_cf) ! End Subroutine Calc_Mutual_Inf + + Subroutine Calc_Renyi_Ent_indep(GRC,List,Nsites,N_SUN,Renyi) +#ifdef MPI + Use mpi +#endif + + Implicit none + + Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Integer, INTENT(IN) :: List(:) + Integer, INTENT(IN) :: Nsites, N_SUN + Complex (Kind=8), INTENT(OUT) :: Renyi + + Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + ! Integer, Dimension(:), Allocatable :: PIVOT + Complex (Kind=8) :: DET, PRODDET, alpha, beta + Integer :: J, IERR, INFO, N_FL, nf, N_FL_half + Integer , Dimension(:,:), Allocatable :: List_tmp + Integer , Dimension(2) :: Nsites_tmp,nf_list,N_SUN_tmp + + EXTERNAL ZGEMM + EXTERNAL ZGETRF + + N_FL = size(GRC,3) + N_FL_half = N_FL/2 + + Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + alpha=CMPLX(2.d0,0.d0,kind(0.d0)) + beta =CMPLX(1.d0,0.d0,kind(0.d0)) + +#ifdef MPI + ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated + if(ENT_SIZE==2) then + + Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) ! new + + DO nf=1,N_FL_half + + DO J = 1, 2 + List_tmp(:,J)=List(:) + Nsites_tmp(J) = Nsites + nf_list(J) = 2*nf-2+J + N_SUN_tmp(J) = N_SUN + enddo + call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET + + Enddo + + if (N_FL/=2*N_FL_half) then + + List_tmp(:,1)=List(:) + call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites,N_fl,N_SUN,PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET + + endif + + Deallocate(GreenA,GreenA_tmp,IDA) + + else + ! if there had been an odd number of task in tempering group / world, set renyi to 0 + Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + endif + + ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call + CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) + Renyi=PRODDET/dble(norm) + ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. + ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. +#endif + + End Subroutine Calc_Renyi_Ent_indep - Subroutine Calc_Renyi_Ent(GRC,List,Nsites,N_SUN,Renyi) + Subroutine Calc_Renyi_Ent_gen_fl(GRC,List,Nsites,N_SUN,Renyi) #ifdef MPI Use mpi #endif @@ -118,7 +204,7 @@ Complex (Kind=8), INTENT(OUT) :: Renyi Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA - Integer, Dimension(:), Allocatable :: PIVOT + ! Integer, Dimension(:), Allocatable :: PIVOT Complex (Kind=8) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav Integer , Dimension(:), Allocatable :: SortedFlavors ! new @@ -137,7 +223,7 @@ if (Nsites(1)==0) start_flav = 1 DO I=2,N_FL x = Nsites(I) - if (Nsites(1)==0) start_flav = start_flav + 1 + if (Nsites(I)==0) start_flav = start_flav + 1 ! there was a bug here J = I-1 DO while(J >= 1) if(Nsites(J) <= x) exit @@ -162,70 +248,6 @@ Allocate(GreenA(dim,2*dim),GreenA_tmp(dim,2*dim),IDA(dim,dim)) ! new DO nf=1,N_FL_half - ! ! We store the reduced Green's function in GreenA_c_tmp (c electrons) - ! ! and GreenA_f_tmp (f electrons) - ! ! The first Nsites columns contains the spin up sector, - ! ! the last Nsites column the spin down sector - ! !DO J = 1, Nsites - ! !DO I = 1, Nsites - ! !GreenA_tmp(I,J) = GRC(List(I), List(J), 2*nf-1) - ! !END DO - ! !END DO - ! nf_eff = SortedFlavors(start_flav+2*nf-1) - - ! DO J = 1, Nsites(nf_eff) - ! Do I = 1, Nsites(nf_eff) - ! GreenA_tmp(I,J) = GRC(List(I,nf_eff),List(J,nf_eff),nf_eff) - ! END DO - ! END Do - - ! nf_eff = SortedFlavors(start_flav+2*nf) - ! DO J = 1, Nsites(nf_eff) - ! DO I = 1, Nsites(nf_eff) - ! GreenA_tmp(I,J+dim) = GRC(List(I,nf_eff), List(J,nf_eff), nf_eff) - ! END DO - ! END DO - ! ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas - ! ! such that GreenA contains the reduced Green's function for two replicas - ! ! and a fixed spin sector. - ! ! CALL MPI_ALLTOALL(GreenA_tmp, Nsites**2, MPI_COMPLEX16, GreenA, Nsites**2, MPI_COMPLEX16, ENTCOMM, IERR) - ! CALL MPI_ALLTOALL(GreenA_tmp, dim**2, MPI_COMPLEX16, GreenA, dim**2, MPI_COMPLEX16, ENTCOMM, IERR) - - ! ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) - ! nf_eff = SortedFlavors(start_flav+2*nf - 1 + ENT_RANK) - ! dim_eff = Nsites(nf_eff) - - ! IDA(1:dim_eff,1:dim_eff) = - GreenA(1:dim_eff, 1:dim_eff) - GreenA(1:dim_eff, dim+1:dim+dim_eff) - ! DO I = 1, dim_eff - ! IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) - ! END DO - ! CALL ZGEMM('n', 'n', dim_eff, dim_eff, dim_eff, alpha, GreenA(1, 1), & - ! & dim, GreenA(1, dim+1), dim, beta, IDA, dim) - ! ! Compute determinant - ! SELECT CASE(dim_eff) - ! CASE (1) - ! DET = IDA(1,1) - ! CASE (2) - ! DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) - ! CASE DEFAULT - ! Allocate(PIVOT(dim_eff)) - ! CALL ZGETRF(dim_eff, dim_eff, IDA, dim, PIVOT, INFO) - ! DET = cmplx(1.D0,0.D0,KIND(0.D0)) - ! DO I = 1, dim_eff - ! IF (PIVOT(I).NE.I) THEN - ! DET = -DET * IDA(I,I) - ! ELSE - ! DET = DET * IDA(I,I) - ! END IF - ! ENDDO - ! Deallocate(PIVOT) - ! END SELECT - ! DET=DET**N_SUN(nf_eff) !! ATTENTION take care of this!!! - ! ! Compute the product of determinants for up and down spin sectors. - ! CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) - ! ! Now each thread contains in PRODDET the full determinant, as obtained by - ! ! a pair of replicas. - DO J = 1, 2 nf_eff = SortedFlavors(start_flav+2*nf-2+J) @@ -247,60 +269,6 @@ call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf_eff),nf_eff,N_SUN(nf_eff),PRODDET,GreenA, GreenA_tmp, IDA) Renyi = Renyi * PRODDET - ! ! We store the reduced Green's function in GreenA_c_tmp (c electrons) - ! ! and GreenA_f_tmp (f electrons) - ! ! The first Nsites columns contains the last flavour sector, - ! ! the last Nsites column are old (Nf>2) or random, but they won't be used - ! nf_eff=SortedFlavors(N_FL) - ! DO J = 1, Nsites - ! DO I = 1, Nsites - ! GreenA_tmp(I,J) = GRC(List(I,nf_eff), List(J,nf_eff), nf_eff) - ! END DO - ! END DO - - ! ! This exchange the last Nsites columns of GreenA_c_tmp between the two replicas - ! ! such that GreenA contains the reduced Green's function for two replicas - ! ! and a fixed spin sector. - ! CALL MPI_ALLTOALL(GreenA_tmp, dim**2, MPI_COMPLEX16, GreenA, dim**2, MPI_COMPLEX16, ENTCOMM, IERR) - - ! DET = cmplx(1.D0,0.D0,KIND(0.D0)) - ! if(ENT_RANK==0) then - - ! ! Compute Identity - GreenA(replica=1) - GreenA(replica=2) + 2 GreenA(replica=1) * GreenA(replica=2) - ! IDA = - GreenA(1:dim, 1:dim) - GreenA(1:dim, dim+1:2*dim) - ! DO I = 1, dim - ! IDA(I,I) = IDA(I,I) + CMPLX(1.d0,0.d0,kind(0.d0)) - ! END DO - ! CALL ZGEMM('n', 'n', dim, dim, dim, alpha, GreenA(1, 1), & - ! & dim, GreenA(1, dim+1), dim, beta, IDA, dim) - ! ! Compute determinant - ! SELECT CASE(dim) - ! CASE (1) - ! DET = IDA(1,1) - ! CASE (2) - ! DET = IDA(1,1) * IDA(2,2) - IDA(1,2) * IDA(2,1) - ! CASE DEFAULT - ! Allocate(PIVOT(dim)) - ! CALL ZGETRF(dim, dim, IDA, dim, PIVOT, INFO) - ! DO I = 1, dim - ! IF (PIVOT(I).NE.I) THEN - ! DET = -DET * IDA(I,I) - ! ELSE - ! DET = DET * IDA(I,I) - ! END IF - ! ENDDO - ! Deallocate(PIVOT) - ! END SELECT - ! Det=Det**N_SUN(nf_eff) - ! endif - - ! ! Compute the product of determinants for up and down spin sectors. - ! CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) - ! ! Now each thread contains in PRODDET the full determinant, as obtained by - ! ! a pair of replicas. - - ! Renyi = Renyi * PRODDET - endif Deallocate(GreenA,GreenA_tmp,IDA) @@ -317,7 +285,106 @@ ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif - End Subroutine Calc_Renyi_Ent + End Subroutine Calc_Renyi_Ent_gen_fl + + Subroutine Calc_Renyi_Ent_gen_all(GRC,List,Nsites,N_SUN,Renyi) +#ifdef MPI + Use mpi +#endif + + Implicit none + + Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Integer, Dimension(:,:,:), INTENT(IN) :: List + Integer, INTENT(IN) :: Nsites(:,:), N_SUN + Complex (Kind=8), INTENT(OUT) :: Renyi + + Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + ! Integer, Dimension(:), Allocatable :: PIVOT + Complex (Kind=8) :: DET, PRODDET, alpha, beta + Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav + Integer :: nc + Integer , Dimension(:), Allocatable :: SortedFlavors + Integer , Dimension(:,:), Allocatable :: List_tmp + Integer , Dimension(2) :: Nsites_tmp,nf_list,N_SUN_tmp + + EXTERNAL ZGEMM + EXTERNAL ZGETRF + + N_FL = size(GRC,3) + Allocate(SortedFlavors(N_FL)) + + Do nc=1,N_SUN + + ! insertion sort for small number of elements, SortedFlavors lists flavors in order of size + start_flav=0 + if (Nsites(1,nc)==0) start_flav = 1 + DO I=2,N_FL + x = Nsites(I,nc) + if (Nsites(I,nc)==0) start_flav = start_flav + 1 ! there was a bug here + J = I-1 + DO while(J >= 1) + if(Nsites(J,nc) <= x) exit + SortedFlavors(J+1) = J + J = J - 1 + end do + SortedFlavors(J+1) = I + END DO + N_FL_half = (N_FL-start_flav)/2 + + Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + alpha=CMPLX(2.d0,0.d0,kind(0.d0)) + beta =CMPLX(1.d0,0.d0,kind(0.d0)) + +#ifdef MPI + ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated + if(ENT_SIZE==2) then + + !Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) + dim = Nsites(SortedFlavors(N_FL),nc) ! new + allocate(List_tmp(dim,2)) + Allocate(GreenA(dim,2*dim),GreenA_tmp(dim,2*dim),IDA(dim,dim)) ! new + + DO nf=1,N_FL_half + + DO J = 1, 2 + nf_eff = SortedFlavors(start_flav+2*nf-2+J) + Nsites_tmp(J)=Nsites(nf_eff,nc) + List_tmp(:,J)=List(:,nf_eff,nc) + N_sun_tmp(J)=1 + nf_list(J)=nf_eff + enddo + call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET + + Enddo + + if (N_FL/=2*N_FL_half+start_flav) then + + nf_eff = SortedFlavors(N_fl) + List_tmp(:,1)=List(:,nf_eff,nc) + + call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf_eff,nc),nf_eff,1,PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET + + endif + + Deallocate(GreenA,GreenA_tmp,IDA) + + else + ! if there had been an odd number of task in tempering group / world, set renyi to 0 + Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + endif + + ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call + CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) + Renyi=PRODDET/dble(norm) + ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. + ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. +#endif + enddo + + End Subroutine Calc_Renyi_Ent_gen_all #ifdef MPI subroutine Calc_Renyi_Ent_pair(GRC,List,Nsites,nf_list,N_SUN,Renyi,GreenA, GreenA_tmp, IDA) -- GitLab From d9ed148b662617d53bdcabd26cc65c8e12a51eca Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Thu, 5 Nov 2020 14:56:20 -0500 Subject: [PATCH 12/50] rewrote some of genall --- Libraries/Modules/entanglement_mod.F90 | 202 ++++++++++++++----------- 1 file changed, 111 insertions(+), 91 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 5ceda8a8..514dcfe7 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -30,20 +30,6 @@ ! to the ALF project or to mark your material in a reasonable way as different from the original version. Module entanglement - INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group - - INTERFACE Calc_Renyi_Ent - MODULE PROCEDURE Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl, Calc_Renyi_Ent_gen_all - END INTERFACE - INTERFACE Init_Entanglement_replicas - MODULE PROCEDURE Init_Entanglement_replicas - END INTERFACE - ! INTERFACE Calc_Mutual_Inf - ! MODULE PROCEDURE Calc_Mutual_Inf - ! END INTERFACE - Contains - -!-------------------------------------------------------------------- !-------------------------------------------------------------------- !> @author @@ -53,11 +39,13 @@ !> This module generates one and two dimensional Bravais lattices. ! !-------------------------------------------------------------------- - ! Used for MPI - ! INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group - ! Contains + INTERFACE Calc_Renyi_Ent + MODULE PROCEDURE Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl, Calc_Renyi_Ent_gen_all + END INTERFACE + Contains !======================================================================== Subroutine Init_Entanglement_replicas(Group_Comm) @@ -146,20 +134,29 @@ Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) + + if (Nsites==0) then + Renyi=0.d0 + return + endif #ifdef MPI ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated if(ENT_SIZE==2) then + allocate(List_tmp(NSITES,2)) Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) ! new + DO J = 1, 2 + List_tmp(:,J)=List(:) + Nsites_tmp(J) = Nsites + N_SUN_tmp(J) = N_SUN + enddo + DO nf=1,N_FL_half DO J = 1, 2 - List_tmp(:,J)=List(:) - Nsites_tmp(J) = Nsites nf_list(J) = 2*nf-2+J - N_SUN_tmp(J) = N_SUN enddo call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) Renyi = Renyi * PRODDET @@ -168,7 +165,6 @@ if (N_FL/=2*N_FL_half) then - List_tmp(:,1)=List(:) call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites,N_fl,N_SUN,PRODDET,GreenA, GreenA_tmp, IDA) Renyi = Renyi * PRODDET @@ -223,7 +219,7 @@ if (Nsites(1)==0) start_flav = 1 DO I=2,N_FL x = Nsites(I) - if (Nsites(I)==0) start_flav = start_flav + 1 ! there was a bug here + if (Nsites(I)==0) start_flav = start_flav + 1 J = I-1 DO while(J >= 1) if(Nsites(J) <= x) exit @@ -232,6 +228,10 @@ end do SortedFlavors(J+1) = I END DO + if(start_flav==N_FL) then + Renyi=0.0d0 + return + endif N_FL_half = (N_FL-start_flav)/2 Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) @@ -287,7 +287,7 @@ End Subroutine Calc_Renyi_Ent_gen_fl - Subroutine Calc_Renyi_Ent_gen_all(GRC,List,Nsites,N_SUN,Renyi) + Subroutine Calc_Renyi_Ent_gen_all(GRC,List,Nsites,Renyi) #ifdef MPI Use mpi #endif @@ -296,93 +296,113 @@ Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:,:,:), INTENT(IN) :: List - Integer, INTENT(IN) :: Nsites(:,:), N_SUN + Integer, INTENT(IN) :: Nsites(:,:) Complex (Kind=8), INTENT(OUT) :: Renyi Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT Complex (Kind=8) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav - Integer :: nc - Integer , Dimension(:), Allocatable :: SortedFlavors - Integer , Dimension(:,:), Allocatable :: List_tmp + Integer :: nc, num_nc + Integer , Dimension(:), Allocatable :: SortedFlavors,N_SUN_fl,df_list + Integer , Dimension(:,:), Allocatable :: List_tmp, eff_ind, eff_ind_inv Integer , Dimension(2) :: Nsites_tmp,nf_list,N_SUN_tmp EXTERNAL ZGEMM EXTERNAL ZGETRF N_FL = size(GRC,3) - Allocate(SortedFlavors(N_FL)) - - Do nc=1,N_SUN - - ! insertion sort for small number of elements, SortedFlavors lists flavors in order of size - start_flav=0 - if (Nsites(1,nc)==0) start_flav = 1 - DO I=2,N_FL - x = Nsites(I,nc) - if (Nsites(I,nc)==0) start_flav = start_flav + 1 ! there was a bug here - J = I-1 - DO while(J >= 1) - if(Nsites(J,nc) <= x) exit - SortedFlavors(J+1) = J - J = J - 1 - end do - SortedFlavors(J+1) = I - END DO - N_FL_half = (N_FL-start_flav)/2 - - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) - alpha=CMPLX(2.d0,0.d0,kind(0.d0)) - beta =CMPLX(1.d0,0.d0,kind(0.d0)) + num_nc = size(List,3) + Allocate(SortedFlavors(num_nc*N_FL),N_SUN_fl(num_nc*N_FL),eff_ind(N_FL,num_nc),eff_ind_inv(2,N_FL*num_nc)) + + I=0 + do nc=1,num_nc + do nf=1,N_FL + I=I+1 + eff_ind(nf,nc)=i + eff_ind_inv(1,I)=nf + eff_ind_inv(2,I)=nc + enddo + enddo + N_SUN_fl=1 + + ! insertion sort for small number of elements, SortedFlavors lists flavors in order of size + start_flav=0 + if (Nsites(1,1)==0) start_flav = 1 + ! might have an update in the future to exchange color and flavor loops--optimization + DO I=2,N_FL*num_nc + x = Nsites(eff_ind_inv(1,I),eff_ind_inv(2,I)) + if (Nsites(eff_ind_inv(1,I),eff_ind_inv(2,I))==0) start_flav = start_flav + 1 ! there was a bug here + J = I-1 + DO while(J >= 1) + if(Nsites(eff_ind_inv(1,J),eff_ind_inv(2,J)) <= x) exit + SortedFlavors(J+1) = J + J = J - 1 + end do + SortedFlavors(J+1) = I + END DO + if(start_flav==N_FL*num_nc) then + Renyi=0.0d0 + return + endif + + N_FL_half = (N_FL*num_nc-start_flav)/2 + + Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + alpha=CMPLX(2.d0,0.d0,kind(0.d0)) + beta =CMPLX(1.d0,0.d0,kind(0.d0)) #ifdef MPI - ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated - if(ENT_SIZE==2) then - - !Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) - dim = Nsites(SortedFlavors(N_FL),nc) ! new - allocate(List_tmp(dim,2)) - Allocate(GreenA(dim,2*dim),GreenA_tmp(dim,2*dim),IDA(dim,dim)) ! new - - DO nf=1,N_FL_half - - DO J = 1, 2 - nf_eff = SortedFlavors(start_flav+2*nf-2+J) - Nsites_tmp(J)=Nsites(nf_eff,nc) - List_tmp(:,J)=List(:,nf_eff,nc) - N_sun_tmp(J)=1 - nf_list(J)=nf_eff - enddo - call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET - - Enddo - - if (N_FL/=2*N_FL_half+start_flav) then - - nf_eff = SortedFlavors(N_fl) - List_tmp(:,1)=List(:,nf_eff,nc) - - call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf_eff,nc),nf_eff,1,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET - - endif + ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated + if(ENT_SIZE==2) then + + !Allocate(GreenA(Nsites,2*Nsites),GreenA_tmp(Nsites,2*Nsites),IDA(Nsites,Nsites)) + nf=eff_ind_inv(1,SortedFlavors(N_FL*num_nc)) + nc=eff_ind_inv(2,SortedFlavors(N_FL*num_nc)) + dim = Nsites(nf,nc) ! new + allocate(List_tmp(dim,2)) + Allocate(GreenA(dim,2*dim),GreenA_tmp(dim,2*dim),IDA(dim,dim)) ! new + + DO I=1,N_FL_half + + DO J = 1, 2 + nf=eff_ind_inv(1,SortedFlavors(start_flav+2*I-2+J)) + nc=eff_ind_inv(2,SortedFlavors(start_flav+2*I-2+J)) + Nsites_tmp(J)=Nsites(nf,nc) + List_tmp(:,J)=List(:,nf,nc) + N_sun_tmp(J)=1 + nf_list(J)=nf + enddo + call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET - Deallocate(GreenA,GreenA_tmp,IDA) + Enddo - else - ! if there had been an odd number of task in tempering group / world, set renyi to 0 - Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + if (N_FL*num_nc/=2*N_FL_half+start_flav) then + + nf=eff_ind_inv(1,SortedFlavors(N_FL*num_nc)) + nc=eff_ind_inv(2,SortedFlavors(N_FL*num_nc)) + List_tmp(:,1)=List(:,nf,nc) + + call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf,nc),nf,1,PRODDET,GreenA, GreenA_tmp, IDA) + Renyi = Renyi * PRODDET + endif - ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) - Renyi=PRODDET/dble(norm) - ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. - ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. + Deallocate(GreenA,GreenA_tmp,IDA) + + else + ! if there had been an odd number of task in tempering group / world, set renyi to 0 + Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + endif + + ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call + CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) + Renyi=PRODDET/dble(norm) + ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. + ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif - enddo + End Subroutine Calc_Renyi_Ent_gen_all -- GitLab From a1cbd23eca8cebe0682e7869fd6324932782031b Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Thu, 5 Nov 2020 15:59:01 -0500 Subject: [PATCH 13/50] bug fix--runs now --- Libraries/Modules/entanglement_mod.F90 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 514dcfe7..228b5108 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -164,7 +164,6 @@ Enddo if (N_FL/=2*N_FL_half) then - call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites,N_fl,N_SUN,PRODDET,GreenA, GreenA_tmp, IDA) Renyi = Renyi * PRODDET @@ -415,7 +414,7 @@ Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:,:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: Nsites(2), N_SUN(2),nf_list(2) ! new - Complex (Kind=8), INTENT(OUT), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (Kind=8), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA Complex (Kind=8), INTENT(OUT) :: Renyi Integer, Dimension(:), Allocatable :: PIVOT @@ -495,7 +494,7 @@ Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: Nsites, N_SUN,nf_eff ! new - Complex (Kind=8), INTENT(OUT), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (Kind=8), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA Complex (Kind=8), INTENT(OUT) :: Renyi Integer, Dimension(:), Allocatable :: PIVOT @@ -503,7 +502,6 @@ Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, start_flav Integer , Dimension(:), Allocatable :: SortedFlavors ! new - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) @@ -513,7 +511,6 @@ ! and GreenA_f_tmp (f electrons) ! The first Nsites columns contains the last flavour sector, ! the last Nsites column are old (Nf>2) or random, but they won't be used - DO J = 1, Nsites DO I = 1, Nsites GreenA_tmp(I,J) = GRC(List(I), List(J), nf_eff) -- GitLab From b9b38515288c386eb76ba2e0195931abb87e15db Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Mon, 9 Nov 2020 15:15:41 +0200 Subject: [PATCH 14/50] Jonas private/public discussion --- Libraries/Modules/entanglement_mod.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 228b5108..a55bd739 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -40,7 +40,9 @@ ! !-------------------------------------------------------------------- ! Used for MPI - INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + private + INTEGER, save :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + public:: INTERFACE Calc_Renyi_Ent MODULE PROCEDURE Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl, Calc_Renyi_Ent_gen_all -- GitLab From fcf82d4bc2c9bfb0e76df088f61d90e3884ad86c Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Tue, 10 Nov 2020 09:39:25 -0500 Subject: [PATCH 15/50] merging into testentanglement --- Libraries/Modules/entanglement_mod.F90 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 228b5108..dc9988b1 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -29,7 +29,7 @@ ! - If you make substantial changes to the program we require you to either consider contributing ! to the ALF project or to mark your material in a reasonable way as different from the original version. - Module entanglement +Module entanglement !-------------------------------------------------------------------- !> @author @@ -43,7 +43,7 @@ INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group INTERFACE Calc_Renyi_Ent - MODULE PROCEDURE Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl, Calc_Renyi_Ent_gen_all + MODULE PROCEDURE Calc_Renyi_Ent_gen_all, Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl END INTERFACE Contains !======================================================================== @@ -194,7 +194,8 @@ Implicit none Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) - Integer, Dimension(:,:), INTENT(IN) :: List ! new + !Integer, Dimension(:,:), INTENT(IN) :: List ! new + Integer, INTENT(IN) :: List(:,:) Integer, INTENT(IN) :: Nsites(:), N_SUN(:) ! new Complex (Kind=8), INTENT(OUT) :: Renyi @@ -372,7 +373,9 @@ N_sun_tmp(J)=1 nf_list(J)=nf enddo + write (*,*) "calling ent_pair" call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) + write (*,*) "calling ent_pair 2" Renyi = Renyi * PRODDET Enddo @@ -562,3 +565,4 @@ #endif end Module entanglement + \ No newline at end of file -- GitLab From 41e69b0fcce902f851341fb3cf33b3f907f13eb9 Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Tue, 10 Nov 2020 11:27:54 -0500 Subject: [PATCH 16/50] added fixes to entanglement --- Libraries/Modules/entanglement_mod.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index dc9988b1..e3454865 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -217,6 +217,7 @@ Module entanglement ! insertion sort for small number of elements, SortedFlavors lists flavors in order of size start_flav=0 if (Nsites(1)==0) start_flav = 1 + SortedFlavors(1) = 1 DO I=2,N_FL x = Nsites(I) if (Nsites(I)==0) start_flav = start_flav + 1 @@ -329,6 +330,7 @@ Module entanglement ! insertion sort for small number of elements, SortedFlavors lists flavors in order of size start_flav=0 if (Nsites(1,1)==0) start_flav = 1 + SortedFlavors(1) = 1 ! might have an update in the future to exchange color and flavor loops--optimization DO I=2,N_FL*num_nc x = Nsites(eff_ind_inv(1,I),eff_ind_inv(2,I)) @@ -341,6 +343,7 @@ Module entanglement end do SortedFlavors(J+1) = I END DO + if(start_flav==N_FL*num_nc) then Renyi=0.0d0 return @@ -373,9 +376,7 @@ Module entanglement N_sun_tmp(J)=1 nf_list(J)=nf enddo - write (*,*) "calling ent_pair" call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) - write (*,*) "calling ent_pair 2" Renyi = Renyi * PRODDET Enddo -- GitLab From 796b85d90ebd903a12ba1643170a491efbbc8b07 Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Tue, 10 Nov 2020 11:58:56 -0500 Subject: [PATCH 17/50] removed extra REDUCEALL --- Libraries/Modules/entanglement_mod.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index e3454865..0dd5caa4 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -41,6 +41,7 @@ Module entanglement !-------------------------------------------------------------------- ! Used for MPI INTEGER :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + Real (kind=kind(0.d0)) :: weight INTERFACE Calc_Renyi_Ent MODULE PROCEDURE Calc_Renyi_Ent_gen_all, Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl @@ -66,6 +67,7 @@ Module entanglement Norm=ISIZE/2 ! number of pairs norm=2*norm ! but each task of pair contributes group=Group_Comm + weight=dble(ISIZE)/dble(Norm) #endif end Subroutine Init_Entanglement_replicas @@ -177,8 +179,7 @@ Module entanglement endif ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) - Renyi=PRODDET/dble(norm) + Renyi=Renyi*weight ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif @@ -280,8 +281,7 @@ Module entanglement endif ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) - Renyi=PRODDET/dble(norm) + Renyi=Renyi*weight ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif @@ -400,8 +400,8 @@ Module entanglement endif ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - CALL MPI_ALLREDUCE(Renyi, PRODDET, 1, MPI_COMPLEX16, MPI_SUM, group, IERR) - Renyi=PRODDET/dble(norm) + Renyi=Renyi*weight + ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif -- GitLab From d3c6cfa9188fd962d97b2fa90335437b390fa4a3 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Wed, 11 Nov 2020 11:13:37 +0200 Subject: [PATCH 18/50] main.F90 modifications --- Prog/main.F90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Prog/main.F90 b/Prog/main.F90 index 7bd30899..38c9cf66 100644 --- a/Prog/main.F90 +++ b/Prog/main.F90 @@ -250,6 +250,10 @@ Program Main igroup = irank/isize_g !Write(6,*) 'irank, Irank_g, Isize_g', irank, irank_g, isize_g #endif + !Initialize entanglement pairs of MPI jobs + !This routine can and should also be called if MPI is not activated + !It will then deactivate the entanglement measurements, i.e., the user does not have to care about this + call Init_Entanglement_replicas(Group_Comm) #ifdef MPI If ( Irank == 0 ) then -- GitLab From 811f5506e28bd6197a93005e6006998351a569d7 Mon Sep 17 00:00:00 2001 From: Emilie Huffman Date: Thu, 12 Nov 2020 01:02:05 +0100 Subject: [PATCH 19/50] working on merge request 90 --- Analysis/cov_mut.F90 | 2 +- Libraries/Modules/entanglement_mod.F90 | 64 +++++++++++++------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Analysis/cov_mut.F90 b/Analysis/cov_mut.F90 index 6b9d8492..7ae1e640 100644 --- a/Analysis/cov_mut.F90 +++ b/Analysis/cov_mut.F90 @@ -1,4 +1,4 @@ -! Copyright (C) 2016 The ALF project +! Copyright (C) 2020 The ALF project ! ! The ALF project is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 0dd5caa4..dbefc34b 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -1,4 +1,4 @@ -! Copyright (C) 2018 The ALF project +! Copyright (C) 2020 The ALF project ! ! The ALF project is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ ! - If you make substantial changes to the program we require you to either consider contributing ! to the ALF project or to mark your material in a reasonable way as different from the original version. -Module entanglement +Module entanglement_mod !-------------------------------------------------------------------- !> @author @@ -81,10 +81,10 @@ Module entanglement ! Implicit none - ! Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + ! Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) ! Integer, Dimension(:), INTENT(IN) :: List_c, List_f ! Integer, INTENT(IN) :: Nsites_c ,Nsites_f - ! Complex (Kind=8), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf + ! Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf ! Integer, Dimension(:), Allocatable :: List_cf ! Integer :: I, J, IERR, INFO, Nsites_cf @@ -115,14 +115,14 @@ Module entanglement Implicit none - Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, INTENT(IN) :: List(:) Integer, INTENT(IN) :: Nsites, N_SUN - Complex (Kind=8), INTENT(OUT) :: Renyi + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi - Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (kind=kind(0.d0)), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT - Complex (Kind=8) :: DET, PRODDET, alpha, beta + Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta Integer :: J, IERR, INFO, N_FL, nf, N_FL_half Integer , Dimension(:,:), Allocatable :: List_tmp Integer , Dimension(2) :: Nsites_tmp,nf_list,N_SUN_tmp @@ -143,7 +143,7 @@ Module entanglement endif #ifdef MPI - ! Check if entanglement replica group is of size 2 such that the second reny entropy can be calculated + ! Check if entanglement replica group is of size 2 such that the second renyi entropy can be calculated if(ENT_SIZE==2) then allocate(List_tmp(NSITES,2)) @@ -171,7 +171,7 @@ Module entanglement endif - Deallocate(GreenA,GreenA_tmp,IDA) + Deallocate(GreenA,GreenA_tmp,IDA,List_tmp) else ! if there had been an odd number of task in tempering group / world, set renyi to 0 @@ -194,15 +194,15 @@ Module entanglement Implicit none - Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) !Integer, Dimension(:,:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: List(:,:) Integer, INTENT(IN) :: Nsites(:), N_SUN(:) ! new - Complex (Kind=8), INTENT(OUT) :: Renyi + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi - Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (kind=kind(0.d0)), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT - Complex (Kind=8) :: DET, PRODDET, alpha, beta + Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav Integer , Dimension(:), Allocatable :: SortedFlavors ! new Integer , Dimension(:,:), Allocatable :: List_tmp @@ -221,7 +221,7 @@ Module entanglement SortedFlavors(1) = 1 DO I=2,N_FL x = Nsites(I) - if (Nsites(I)==0) start_flav = start_flav + 1 + if (x==0) start_flav = start_flav + 1 J = I-1 DO while(J >= 1) if(Nsites(J) <= x) exit @@ -273,7 +273,7 @@ Module entanglement endif - Deallocate(GreenA,GreenA_tmp,IDA) + Deallocate(GreenA,GreenA_tmp,IDA,List_tmp) else ! if there had been an odd number of task in tempering group / world, set renyi to 0 @@ -295,14 +295,14 @@ Module entanglement Implicit none - Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:,:,:), INTENT(IN) :: List Integer, INTENT(IN) :: Nsites(:,:) - Complex (Kind=8), INTENT(OUT) :: Renyi + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi - Complex (Kind=8), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA + Complex (kind=kind(0.d0)), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT - Complex (Kind=8) :: DET, PRODDET, alpha, beta + Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav Integer :: nc, num_nc Integer , Dimension(:), Allocatable :: SortedFlavors,N_SUN_fl,df_list @@ -334,7 +334,7 @@ Module entanglement ! might have an update in the future to exchange color and flavor loops--optimization DO I=2,N_FL*num_nc x = Nsites(eff_ind_inv(1,I),eff_ind_inv(2,I)) - if (Nsites(eff_ind_inv(1,I),eff_ind_inv(2,I))==0) start_flav = start_flav + 1 ! there was a bug here + if (x==0) start_flav = start_flav + 1 J = I-1 DO while(J >= 1) if(Nsites(eff_ind_inv(1,J),eff_ind_inv(2,J)) <= x) exit @@ -392,7 +392,7 @@ Module entanglement endif - Deallocate(GreenA,GreenA_tmp,IDA) + Deallocate(GreenA,GreenA_tmp,IDA,List_tmp) else ! if there had been an odd number of task in tempering group / world, set renyi to 0 @@ -415,14 +415,14 @@ Module entanglement Implicit none - Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:,:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: Nsites(2), N_SUN(2),nf_list(2) ! new - Complex (Kind=8), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA - Complex (Kind=8), INTENT(OUT) :: Renyi + Complex (kind=kind(0.d0)), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Integer, Dimension(:), Allocatable :: PIVOT - Complex (Kind=8) :: DET, PRODDET, alpha, beta + Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, nf_eff, start_flav Integer , Dimension(:), Allocatable :: SortedFlavors ! new @@ -495,14 +495,14 @@ Module entanglement Implicit none - Complex (Kind=8), INTENT(IN) :: GRC(:,:,:) + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: Nsites, N_SUN,nf_eff ! new - Complex (Kind=8), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA - Complex (Kind=8), INTENT(OUT) :: Renyi + Complex (kind=kind(0.d0)), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Integer, Dimension(:), Allocatable :: PIVOT - Complex (Kind=8) :: DET, PRODDET, alpha, beta + Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, start_flav Integer , Dimension(:), Allocatable :: SortedFlavors ! new @@ -565,5 +565,5 @@ Module entanglement end subroutine Calc_Renyi_Ent_single #endif - end Module entanglement - \ No newline at end of file + end Module entanglement_mod + -- GitLab From d83db1bbc4161ebf2e89100e116d4a510faf72fe Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Sat, 14 Nov 2020 19:15:26 +0200 Subject: [PATCH 20/50] turning subroutines into functions and adding mutual information --- Libraries/Modules/entanglement_mod.F90 | 223 +++++++++++++++++-------- 1 file changed, 155 insertions(+), 68 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index 18007b3a..c9dd9a7a 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -40,14 +40,15 @@ Module entanglement_mod ! !-------------------------------------------------------------------- ! Used for MPI - private - INTEGER, save :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group - Real (kind=kind(0.d0)), save :: weight - public:: + INTEGER, save, private :: ENTCOMM, ENT_RANK, ENT_SIZE=0, Norm, group + Real (kind=kind(0.d0)), save, private :: weight INTERFACE Calc_Renyi_Ent MODULE PROCEDURE Calc_Renyi_Ent_gen_all, Calc_Renyi_Ent_indep, Calc_Renyi_Ent_gen_fl END INTERFACE + INTERFACE Calc_Mutual_Inf + MODULE PROCEDURE Calc_Mutual_Inf_indep, Calc_Mutual_Inf_gen_fl, Calc_Mutual_Inf_gen_all + END INTERFACE Contains !======================================================================== @@ -79,38 +80,129 @@ Module entanglement_mod ! The algorithm works only for an MPI program ! We partition the nodes into groups of 2 replicas: ! ! (n, n+1), with n=0,2,... - ! Subroutine Calc_Mutual_Inf(GRC,List_c,Nsites_c,List_f,Nsites_f,Renyi_c,Renyi_f,Renyi_cf) + Subroutine Calc_Mutual_Inf_indep(GRC,List_c,Nsites_c,List_f,Nsites_f,N_SUN,Renyi_c,Renyi_f,Renyi_cf) + + Implicit none + + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) + Integer, Dimension(:), INTENT(IN) :: List_c, List_f + Integer, INTENT(IN) :: Nsites_c ,Nsites_f, N_SUN + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf + + Integer, Dimension(:), Allocatable :: List_cf + Integer :: I, J, IERR, INFO, Nsites_cf + + Nsites_cf=Nsites_c+Nsites_f + + allocate(List_cf(Nsites_cf)) + + DO I = 1, Nsites_c + List_cf(I) = List_c(I) + END DO + DO I = 1, Nsites_f + List_cf(I+Nsites_c) = List_f(I) + END DO + + Renyi_c = Calc_Renyi_Ent_indep(GRC,List_c,Nsites_c,N_SUN) + Renyi_f = Calc_Renyi_Ent_indep(GRC,List_f,Nsites_f,N_SUN) + Renyi_cf = Calc_Renyi_Ent_indep(GRC,List_cf,Nsites_cf,N_SUN) + + deallocate(List_cf) + + End Subroutine Calc_Mutual_Inf_indep + +!======================================================================== + ! Calculation of the Renyi entanglement entropy + ! The algorithm works only for an MPI program + ! We partition the nodes into groups of 2 replicas: + ! ! (n, n+1), with n=0,2,... + Subroutine Calc_Mutual_Inf_gen_fl(GRC,List_c,Nsites_c,List_f,Nsites_f,N_SUN,Renyi_c,Renyi_f,Renyi_cf) + + Implicit none + + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) + Integer, Dimension(:,:), INTENT(IN) :: List_c, List_f + Integer, Dimension(:), INTENT(IN) :: Nsites_c ,Nsites_f, N_SUN + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf + + Integer, Allocatable :: List_cf(:,:), Nsites_cf(:) + Integer :: I, J, IERR, INFO, N_FL, Nsites_cf_max + + N_FL=size(GRC,3) + Nsites_cf_max=0 + do I=1,N_FL + Nsites_cf(I)=Nsites_c(I)+Nsites_f(I) + if (Nsites_cf(I)>Nsites_cf_max) Nsites_cf_max=Nsites_cf(I) + enddo + + allocate(List_cf(Nsites_cf_max,N_FL)) + + do J=1,N_FL + DO I = 1, Nsites_c(J) + List_cf(I,J) = List_c(I,J) + END DO + DO I = 1, Nsites_f(J) + List_cf(I+Nsites_c(J),J) = List_f(I,J) + END DO + enddo + + Renyi_c = Calc_Renyi_Ent_gen_fl(GRC,List_c,Nsites_c,N_SUN) + Renyi_f = Calc_Renyi_Ent_gen_fl(GRC,List_f,Nsites_f,N_SUN) + Renyi_cf = Calc_Renyi_Ent_gen_fl(GRC,List_cf,Nsites_cf,N_SUN) + + deallocate(List_cf) + + End Subroutine Calc_Mutual_Inf_gen_fl + +!======================================================================== + ! Calculation of the Renyi entanglement entropy + ! The algorithm works only for an MPI program + ! We partition the nodes into groups of 2 replicas: + ! ! (n, n+1), with n=0,2,... + Subroutine Calc_Mutual_Inf_gen_all(GRC,List_c,Nsites_c,List_f,Nsites_f,N_SUN,Renyi_c,Renyi_f,Renyi_cf) - ! Implicit none + Implicit none - ! Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) - ! Integer, Dimension(:), INTENT(IN) :: List_c, List_f - ! Integer, INTENT(IN) :: Nsites_c ,Nsites_f - ! Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) + Integer, Dimension(:,:,:), INTENT(IN) :: List_c, List_f + Integer, Dimension(:,:), INTENT(IN) :: Nsites_c ,Nsites_f, N_SUN + Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf - ! Integer, Dimension(:), Allocatable :: List_cf - ! Integer :: I, J, IERR, INFO, Nsites_cf + Integer, Allocatable :: List_cf(:,:,:), Nsites_cf(:,:) + Integer :: I, J, IERR, INFO, N_FL, Nsites_cf_max, nc, num_nc - ! Nsites_cf=Nsites_c+Nsites_f + N_FL=size(GRC,3) + num_nc=size(List_f,3) + Nsites_cf_max=0 + do nc=1,num_nc + do I=1,N_FL + Nsites_cf(I,nc)=Nsites_c(I,nc)+Nsites_f(I,nc) + if (Nsites_cf(I,nc)>Nsites_cf_max) Nsites_cf_max=Nsites_cf(I,nc) + enddo + enddo - ! allocate(List_cf(Nsites_cf)) + allocate(List_cf(Nsites_cf_max,N_FL,num_nc)) - ! DO I = 1, Nsites_c - ! List_cf(I) = List_c(I) - ! END DO - ! DO I = 1, Nsites_f - ! List_cf(I+Nsites_c) = List_f(I) - ! END DO + do nc=1, num_nc + do J=1,N_FL + DO I = 1, Nsites_c(J,nc) + List_cf(I,J,nc) = List_c(I,J,nc) + END DO + DO I = 1, Nsites_f(J,nc) + List_cf(I+Nsites_c(J,nc),J,nc) = List_f(I,J,nc) + END DO + enddo + enddo - ! Call Calc_Renyi_Ent(GRC,List_c,Nsites_c,Renyi_c) - ! Call Calc_Renyi_Ent(GRC,List_f,Nsites_f,Renyi_f) - ! Call Calc_Renyi_Ent(GRC,List_cf,Nsites_cf,Renyi_cf) + Renyi_c = Calc_Renyi_Ent_gen_all(GRC,List_c,Nsites_c) + Renyi_f = Calc_Renyi_Ent_gen_all(GRC,List_f,Nsites_f) + Renyi_cf = Calc_Renyi_Ent_gen_all(GRC,List_cf,Nsites_cf) - ! deallocate(List_cf) + deallocate(List_cf) - ! End Subroutine Calc_Mutual_Inf + End Subroutine Calc_Mutual_Inf_gen_all - Subroutine Calc_Renyi_Ent_indep(GRC,List,Nsites,N_SUN,Renyi) + Complex (kind=kind(0.d0)) function Calc_Renyi_Ent_indep(GRC,List,Nsites,N_SUN) #ifdef MPI Use mpi #endif @@ -120,7 +212,6 @@ Module entanglement_mod Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, INTENT(IN) :: List(:) Integer, INTENT(IN) :: Nsites, N_SUN - Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Complex (kind=kind(0.d0)), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT @@ -135,12 +226,12 @@ Module entanglement_mod N_FL = size(GRC,3) N_FL_half = N_FL/2 - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_indep=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) if (Nsites==0) then - Renyi=0.d0 + Calc_Renyi_Ent_indep=0.d0 return endif @@ -162,14 +253,14 @@ Module entanglement_mod DO J = 1, 2 nf_list(J) = 2*nf-2+J enddo - call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET + PRODET = Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) + Calc_Renyi_Ent_indep = Calc_Renyi_Ent_indep * PRODDET Enddo if (N_FL/=2*N_FL_half) then - call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites,N_fl,N_SUN,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET + PRODDET = Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites,N_fl,N_SUN,PRODDET,GreenA, GreenA_tmp, IDA) + Calc_Renyi_Ent_indep = Calc_Renyi_Ent_indep * PRODDET endif @@ -177,19 +268,19 @@ Module entanglement_mod else ! if there had been an odd number of task in tempering group / world, set renyi to 0 - Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_indep=CMPLX(0.d0,0.d0,kind(0.d0)) endif ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - Renyi=Renyi*weight + Calc_Renyi_Ent_indep=Calc_Renyi_Ent_indep*weight ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif - End Subroutine Calc_Renyi_Ent_indep + End function Calc_Renyi_Ent_indep - Subroutine Calc_Renyi_Ent_gen_fl(GRC,List,Nsites,N_SUN,Renyi) + Complex (kind=kind(0.d0)) function Calc_Renyi_Ent_gen_fl(GRC,List,Nsites,N_SUN) #ifdef MPI Use mpi #endif @@ -200,7 +291,6 @@ Module entanglement_mod !Integer, Dimension(:,:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: List(:,:) Integer, INTENT(IN) :: Nsites(:), N_SUN(:) ! new - Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Complex (kind=kind(0.d0)), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT @@ -233,12 +323,12 @@ Module entanglement_mod SortedFlavors(J+1) = I END DO if(start_flav==N_FL) then - Renyi=0.0d0 + Calc_Renyi_Ent_gen_fl=0.0d0 return endif N_FL_half = (N_FL-start_flav)/2 - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_gen_fl=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) @@ -260,8 +350,8 @@ Module entanglement_mod N_sun_tmp(J)=N_SUN(nf_eff) nf_list(J)=nf_eff enddo - call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET + PRODDET = Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) + Calc_Renyi_Ent_gen_fl = Calc_Renyi_Ent_gen_fl * PRODDET Enddo @@ -270,8 +360,8 @@ Module entanglement_mod nf_eff = SortedFlavors(N_fl) List_tmp(:,1)=List(:,nf_eff) - call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf_eff),nf_eff,N_SUN(nf_eff),PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET + PRODDET = Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf_eff),nf_eff,N_SUN(nf_eff),PRODDET,GreenA, GreenA_tmp, IDA) + Calc_Renyi_Ent_gen_fl = Calc_Renyi_Ent_gen_fl * PRODDET endif @@ -279,18 +369,18 @@ Module entanglement_mod else ! if there had been an odd number of task in tempering group / world, set renyi to 0 - Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_gen_fl=CMPLX(0.d0,0.d0,kind(0.d0)) endif ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - Renyi=Renyi*weight + Calc_Renyi_Ent_gen_fl=Calc_Renyi_Ent_gen_fl*weight ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif - End Subroutine Calc_Renyi_Ent_gen_fl + End function Calc_Renyi_Ent_gen_fl - Subroutine Calc_Renyi_Ent_gen_all(GRC,List,Nsites,Renyi) + Complex (kind=kind(0.d0)) function Calc_Renyi_Ent_gen_all(GRC,List,Nsites) #ifdef MPI Use mpi #endif @@ -300,7 +390,6 @@ Module entanglement_mod Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:,:,:), INTENT(IN) :: List Integer, INTENT(IN) :: Nsites(:,:) - Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Complex (kind=kind(0.d0)), Dimension(:,:), Allocatable :: GreenA, GreenA_tmp, IDA ! Integer, Dimension(:), Allocatable :: PIVOT @@ -347,13 +436,13 @@ Module entanglement_mod END DO if(start_flav==N_FL*num_nc) then - Renyi=0.0d0 + Calc_Renyi_Ent_gen_all=0.0d0 return endif N_FL_half = (N_FL*num_nc-start_flav)/2 - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_gen_all=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) @@ -378,8 +467,8 @@ Module entanglement_mod N_sun_tmp(J)=1 nf_list(J)=nf enddo - call Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET + PRODDET = Calc_Renyi_Ent_pair(GRC,List_tmp,Nsites_tmp,nf_list,N_SUN_tmp,GreenA, GreenA_tmp, IDA) + Calc_Renyi_Ent_gen_all = Calc_Renyi_Ent_gen_all * PRODDET Enddo @@ -389,8 +478,8 @@ Module entanglement_mod nc=eff_ind_inv(2,SortedFlavors(N_FL*num_nc)) List_tmp(:,1)=List(:,nf,nc) - call Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf,nc),nf,1,PRODDET,GreenA, GreenA_tmp, IDA) - Renyi = Renyi * PRODDET + proddet = Calc_Renyi_Ent_single(GRC,List_tmp(:,1),Nsites(nf,nc),nf,1,PRODDET,GreenA, GreenA_tmp, IDA) + Calc_Renyi_Ent_gen_all = Calc_Renyi_Ent_gen_all * PRODDET endif @@ -398,21 +487,21 @@ Module entanglement_mod else ! if there had been an odd number of task in tempering group / world, set renyi to 0 - Renyi=CMPLX(0.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_gen_all=CMPLX(0.d0,0.d0,kind(0.d0)) endif ! average over all pairs of replicas, the single task contributes nothing even so it takes part in the call - Renyi=Renyi*weight + Calc_Renyi_Ent_gen_all=Calc_Renyi_Ent_gen_all*weight ! At this point, each task of the temepering group / world returns the same averaged value of the pairs, including the possible "free"/ unpaired one. ! This mechanisms leads to some syncronization, but I (Johannes) am lacking a better way to treat odd number of tasks. #endif - End Subroutine Calc_Renyi_Ent_gen_all + End function Calc_Renyi_Ent_gen_all #ifdef MPI - subroutine Calc_Renyi_Ent_pair(GRC,List,Nsites,nf_list,N_SUN,Renyi,GreenA, GreenA_tmp, IDA) + Complex (kind=kind(0.d0)) function Calc_Renyi_Ent_pair(GRC,List,Nsites,nf_list,N_SUN,GreenA, GreenA_tmp, IDA) Use mpi Implicit none @@ -421,7 +510,6 @@ Module entanglement_mod Integer, Dimension(:,:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: Nsites(2), N_SUN(2),nf_list(2) ! new Complex (kind=kind(0.d0)), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA - Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Integer, Dimension(:), Allocatable :: PIVOT Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta @@ -429,7 +517,7 @@ Module entanglement_mod Integer , Dimension(:), Allocatable :: SortedFlavors ! new - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_pair=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) @@ -489,10 +577,10 @@ Module entanglement_mod CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) ! Now each thread contains in PRODDET the full determinant, as obtained by ! a pair of replicas. - Renyi = Renyi * PRODDET - end subroutine Calc_Renyi_Ent_pair + Calc_Renyi_Ent_pair = Calc_Renyi_Ent_pair * PRODDET + end function Calc_Renyi_Ent_pair - subroutine Calc_Renyi_Ent_single(GRC,List,Nsites,nf_eff,N_SUN,Renyi,GreenA, GreenA_tmp, IDA) + Complex (Kind=8) function Calc_Renyi_Ent_single(GRC,List,Nsites,nf_eff,N_SUN,GreenA, GreenA_tmp, IDA) Use mpi Implicit none @@ -501,14 +589,13 @@ Module entanglement_mod Integer, Dimension(:), INTENT(IN) :: List ! new Integer, INTENT(IN) :: Nsites, N_SUN,nf_eff ! new Complex (kind=kind(0.d0)), INTENT(OUT), Dimension(:,:) :: GreenA, GreenA_tmp, IDA - Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi Integer, Dimension(:), Allocatable :: PIVOT Complex (kind=kind(0.d0)) :: DET, PRODDET, alpha, beta Integer :: I, J, IERR, INFO, N_FL, nf, N_FL_half, x, dim, dim_eff, start_flav Integer , Dimension(:), Allocatable :: SortedFlavors ! new - Renyi=CMPLX(1.d0,0.d0,kind(0.d0)) + Calc_Renyi_Ent_single=CMPLX(1.d0,0.d0,kind(0.d0)) alpha=CMPLX(2.d0,0.d0,kind(0.d0)) beta =CMPLX(1.d0,0.d0,kind(0.d0)) @@ -563,8 +650,8 @@ Module entanglement_mod CALL MPI_ALLREDUCE(DET, PRODDET, 1, MPI_COMPLEX16, MPI_PROD, ENTCOMM, IERR) ! Now each thread contains in PRODDET the full determinant, as obtained by ! a pair of replicas. - Renyi = Renyi * PRODDET - end subroutine Calc_Renyi_Ent_single + Calc_Renyi_Ent_single = Calc_Renyi_Ent_single * PRODDET + end function Calc_Renyi_Ent_single #endif end Module entanglement_mod -- GitLab From fb2153e02cc8ab3ae00416917c4449e8f8bfeb77 Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Laptop)" Date: Sat, 14 Nov 2020 21:11:05 +0200 Subject: [PATCH 21/50] adding predefined observables --- Libraries/Modules/entanglement_mod.F90 | 4 +- Prog/Predefined_Obs_mod.F90 | 127 ++++++++++++++++++++++++- Prog/main.F90 | 1 + 3 files changed, 128 insertions(+), 4 deletions(-) diff --git a/Libraries/Modules/entanglement_mod.F90 b/Libraries/Modules/entanglement_mod.F90 index c9dd9a7a..0adbf9de 100644 --- a/Libraries/Modules/entanglement_mod.F90 +++ b/Libraries/Modules/entanglement_mod.F90 @@ -159,13 +159,13 @@ Module entanglement_mod ! The algorithm works only for an MPI program ! We partition the nodes into groups of 2 replicas: ! ! (n, n+1), with n=0,2,... - Subroutine Calc_Mutual_Inf_gen_all(GRC,List_c,Nsites_c,List_f,Nsites_f,N_SUN,Renyi_c,Renyi_f,Renyi_cf) + Subroutine Calc_Mutual_Inf_gen_all(GRC,List_c,Nsites_c,List_f,Nsites_f,Renyi_c,Renyi_f,Renyi_cf) Implicit none Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:) Integer, Dimension(:,:,:), INTENT(IN) :: List_c, List_f - Integer, Dimension(:,:), INTENT(IN) :: Nsites_c ,Nsites_f, N_SUN + Integer, Dimension(:,:), INTENT(IN) :: Nsites_c ,Nsites_f Complex (kind=kind(0.d0)), INTENT(OUT) :: Renyi_c, Renyi_f, Renyi_cf Integer, Allocatable :: List_cf(:,:,:), Nsites_cf(:,:) diff --git a/Prog/Predefined_Obs_mod.F90 b/Prog/Predefined_Obs_mod.F90 index 166047e3..41166feb 100644 --- a/Prog/Predefined_Obs_mod.F90 +++ b/Prog/Predefined_Obs_mod.F90 @@ -43,10 +43,19 @@ Use Observables Use Lattices_v3 + Use entanglement_mod use iso_fortran_env, only: output_unit, error_unit Implicit none - + + INTERFACE Predefined_Obs_scal_Renyi_Ent + MODULE PROCEDURE Predefined_Obs_scal_Renyi_Ent_gen_all, Predefined_Obs_scal_Renyi_Ent_indep, & + & Predefined_Obs_scal_Renyi_Ent_gen_fl + END INTERFACE + INTERFACE Predefined_Obs_scal_Mutual_Inf + MODULE PROCEDURE Predefined_Obs_scal_Mutual_Inf_indep, Predefined_Obs_scal_Mutual_Inf_gen_fl, & + & Predefined_Obs_scal_Mutual_Inf_gen_all + END INTERFACE contains !------------------------------------------------------------------- @@ -503,6 +512,120 @@ enddo end Subroutine Predefined_Obs_tau_Den_measure - + + + Subroutine Predefined_Obs_scal_Renyi_Ent_indep(GRC, List, Nsites, N_SUN, ZS, ZP, Obs ) + + Implicit none + Integer, Dimension(:), INTENT(IN) :: List + Integer, INTENT(IN) :: Nsites, N_SUN + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:), ZS, ZP + Type (Obser_Vec), Intent(inout) :: Obs + + Complex (kind=kind(0.d0)) :: Renyi + + Renyi = Calc_Renyi_Ent_indep(GRC, List, Nsites, N_SUN) + + Obs%N = Obs%N + 1 + Obs%Ave_sign = Obs%Ave_sign + real(ZS,kind(0.d0)) + Obs%Obs_vec(1) = Renyi* ZP*ZS + + end Subroutine Predefined_Obs_scal_Renyi_Ent_indep + + Subroutine Predefined_Obs_scal_Renyi_Ent_gen_fl(GRC, List, Nsites, N_SUN, ZS, ZP, Obs ) + + Implicit none + Integer, Dimension(:,:), INTENT(IN) :: List + Integer, Dimension(:), INTENT(IN) :: Nsites, N_SUN + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:), ZS, ZP + Type (Obser_Vec), Intent(inout) :: Obs + + Complex (kind=kind(0.d0)) :: Renyi + + Renyi = Calc_Renyi_Ent_gen_fl(GRC, List, Nsites, N_SUN) + + Obs%N = Obs%N + 1 + Obs%Ave_sign = Obs%Ave_sign + real(ZS,kind(0.d0)) + Obs%Obs_vec(1) = Renyi* ZP*ZS + + end Subroutine Predefined_Obs_scal_Renyi_Ent_gen_fl + + Subroutine Predefined_Obs_scal_Renyi_Ent_gen_all(GRC, List, Nsites, ZS, ZP, Obs ) + + Implicit none + Integer, Dimension(:,:,:), INTENT(IN) :: List + Integer, Dimension(:,:), INTENT(IN) :: Nsites + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:), ZS, ZP + Type (Obser_Vec), Intent(inout) :: Obs + + Complex (kind=kind(0.d0)) :: Renyi + + Renyi = Calc_Renyi_Ent_gen_all(GRC, List, Nsites) + + Obs%N = Obs%N + 1 + Obs%Ave_sign = Obs%Ave_sign + real(ZS,kind(0.d0)) + Obs%Obs_vec(1) = Renyi* ZP*ZS + + end Subroutine Predefined_Obs_scal_Renyi_Ent_gen_all + + Subroutine Predefined_Obs_scal_Mutual_Inf_indep(GRC, List_c, Nsites_c, List_f, Nsites_f, N_SUN, ZS, ZP, Obs ) + + Implicit none + Integer, Dimension(:), INTENT(IN) :: List_c, List_f + Integer, INTENT(IN) :: Nsites_c ,Nsites_f, N_SUN + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:), ZS, ZP + Type (Obser_Vec), Intent(inout) :: Obs + + Complex (kind=kind(0.d0)) :: Renyi_c, Renyi_f, Renyi_cf + + call Calc_Mutual_Inf_indep(GRC, List_c, Nsites_c, List_f, Nsites_f, N_SUN, Renyi_c, Renyi_f, Renyi_cf) + + Obs%N = Obs%N + 1 + Obs%Ave_sign = Obs%Ave_sign + real(ZS,kind(0.d0)) + Obs%Obs_vec(1) = Renyi_c* ZP*ZS + Obs%Obs_vec(2) = Renyi_f* ZP*ZS + Obs%Obs_vec(3) = Renyi_cf* ZP*ZS + + end Subroutine Predefined_Obs_scal_Mutual_Inf_indep + + Subroutine Predefined_Obs_scal_Mutual_Inf_gen_fl(GRC, List_c, Nsites_c, List_f, Nsites_f, N_SUN, ZS, ZP, Obs ) + + Implicit none + Integer, Dimension(:,:), INTENT(IN) :: List_c, List_f + Integer, Dimension(:), INTENT(IN) :: Nsites_c ,Nsites_f, N_SUN + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:), ZS, ZP + Type (Obser_Vec), Intent(inout) :: Obs + + Complex (kind=kind(0.d0)) :: Renyi_c, Renyi_f, Renyi_cf + + call Calc_Mutual_Inf_gen_fl(GRC, List_c, Nsites_c, List_f, Nsites_f, N_SUN, Renyi_c, Renyi_f, Renyi_cf) + + Obs%N = Obs%N + 1 + Obs%Ave_sign = Obs%Ave_sign + real(ZS,kind(0.d0)) + Obs%Obs_vec(1) = Renyi_c* ZP*ZS + Obs%Obs_vec(2) = Renyi_f* ZP*ZS + Obs%Obs_vec(3) = Renyi_cf* ZP*ZS + + end Subroutine Predefined_Obs_scal_Mutual_Inf_gen_fl + + Subroutine Predefined_Obs_scal_Mutual_Inf_gen_all(GRC, List_c, Nsites_c, List_f, Nsites_f, ZS, ZP, Obs ) + + Implicit none + Integer, Dimension(:,:,:), INTENT(IN) :: List_c, List_f + Integer, Dimension(:,:), INTENT(IN) :: Nsites_c ,Nsites_f + Complex (kind=kind(0.d0)), INTENT(IN) :: GRC(:,:,:), ZS, ZP + Type (Obser_Vec), Intent(inout) :: Obs + + Complex (kind=kind(0.d0)) :: Renyi_c, Renyi_f, Renyi_cf + + call Calc_Mutual_Inf_gen_all(GRC, List_c, Nsites_c, List_f, Nsites_f, Renyi_c, Renyi_f, Renyi_cf) + + Obs%N = Obs%N + 1 + Obs%Ave_sign = Obs%Ave_sign + real(ZS,kind(0.d0)) + Obs%Obs_vec(1) = Renyi_c* ZP*ZS + Obs%Obs_vec(2) = Renyi_f* ZP*ZS + Obs%Obs_vec(3) = Renyi_cf* ZP*ZS + + end Subroutine Predefined_Obs_scal_Mutual_Inf_gen_all end Module Predefined_Obs diff --git a/Prog/main.F90 b/Prog/main.F90 index 38c9cf66..32453453 100644 --- a/Prog/main.F90 +++ b/Prog/main.F90 @@ -124,6 +124,7 @@ Program Main Use UDV_State_mod Use Wrapgr_mod Use Fields_mod + use entanglement_mod use iso_fortran_env, only: output_unit, error_unit #ifdef MPI Use mpi -- GitLab From 7b29d91eeec3ee3292229f51450b2217abc39208 Mon Sep 17 00:00:00 2001 From: Francesco Parisen Toldin Date: Sun, 15 Nov 2020 23:46:50 +0100 Subject: [PATCH 22/50] documentation for the renyi entropy routines --- Documentation/renyi.tex | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Documentation/renyi.tex b/Documentation/renyi.tex index fbd566c9..bd867e8a 100644 --- a/Documentation/renyi.tex +++ b/Documentation/renyi.tex @@ -8,4 +8,37 @@ %----------------------------------------------------------------------------------- \subsubsection{R{\'e}nyi Entropy} %----------------------------------------------------------------------------------- +The provided module \texttt{entanglement\_mod.F90} allows to compute the $2^{\rm o}$ R\'enyi entropy $S_2$ for a subsystem. Only real-space partitions are currently supported. Routines with different level of specialization, are provided. +\begin{lstlisting}[style=fortran] +Obs = Calc_Renyi_Ent_gen_all(GRC,List,Nsites) +\end{lstlisting} + +This returns an observable \texttt{Obs} such that $\langle\texttt{Obs}\rangle=e^{-S_2}$. \texttt{List(:, N\_FL, N\_SUN)} is a three-dimensional array that contains, for every flavor and color index the list of lattice sites pertaining to the subsystem. \texttt{Nsites(N\_FL, N\_SUN)} is a bidimensional array that provides the number of lattice sites in the subsystem for every flavor and color index. + +\begin{lstlisting}[style=fortran] +Obs = Calc_Renyi_Ent_gen_fl(GRC,List,Nsites,N_SUN) +\end{lstlisting} +This computes the observable for the R\'enyi entropy for a subsystem whose degrees of freedom, for a given flavor index, have a common value of color indexes. \texttt{List(:, N\_FL)} is a bidimensional array that contains, for every flavor index, the list of lattice sites of the subsystem. \texttt{Nsites(N\_FL)} contains the number of sites in the subsystem for any given flavor index. \texttt{N\_SUN(N\_FL)} contains the number of color indexes for a given flavor index. + +\begin{lstlisting}[style=fortran] +Obs = Calc_Renyi_Ent_indep(GRC,List,Nsites,N_SUN) +\end{lstlisting} +Same as before, for a subsystem whose lattice degrees of freedom are flavor- and color-independent. \texttt{List(:)} is a one-dimensional array containing the lattice sites of the subsystem. +\texttt{N\_SUN} is the number of color indexes belonging to the subsystem. +For every element \texttt{I} of \texttt{List}, the subsystem contains all degrees of freedom with site index \texttt{I}, any flavor index, and \texttt{1} \ldots \texttt{N\_SUN} color index. + +\begin{lstlisting}[style=fortran] +Calc_Mutual_Inf_gen_all(GRC,List_c,Nsites_c,List_f,Nsites_f,Renyi_c,Renyi_f,Renyi_cf) +\end{lstlisting} +This routine computes the second R\'enyi entropy observables needed to extract the mutual information between a subsystem $c$ and $f$. \texttt{List\_c}, and \texttt{Nsites} are input parameters describing the subsystem $c$, with the same convention as for \texttt{Calc\_Renyi\_Ent\_gen\_all}. \texttt{List\_f} and \texttt{Nsites\_f} are the corresponding input parameters for the subsystem $f$. \texttt{Renyi\_c}, \texttt{Renyi\_f}, and \texttt{Renyi\_cf} are the output variables, containing the R\'enyi observables for the subsystem $c$, $f$, and $c\cup f$. The mutual information between $c$ and $f$ is $I_2=-\ln \langle \texttt{Renyi\_c}\rangle -\ln \langle \texttt{Renyi\_f}\rangle +\ln \langle \texttt{Renyi\_cf}\rangle$. + +\begin{lstlisting}[style=fortran,breaklines=true] +Call Calc_Mutual_Inf_indep(GRC,List_c,Nsites_c,List_f,Nsites_f,N_SUN,Renyi_c,Renyi_f,Renyi_cf) +\end{lstlisting} +This is the analog of \texttt{Calc\_Mutual\_Inf\_gen\_all} for two subsytems with the same assumptions and convention of \texttt{Calc\_Renyi\_Ent\_gen\_fl}. + +\begin{lstlisting}[style=fortran,breaklines=true] +Calc_Mutual_Inf_gen_fl(GRC,List_c,Nsites_c,List_f,Nsites_f,N_SUN,Renyi_c,Renyi_f,Renyi_cf) +\end{lstlisting} +This is the analog of \texttt{Calc\_Mutual\_Inf\_gen\_all} for two subsytems with the same assumptions and convention of \texttt{Calc\_Renyi\_Ent\_indep}. -- GitLab From ca40bf8f793fd5e7f0ad63722c26a9a10196122e Mon Sep 17 00:00:00 2001 From: "Johannes Hofmann (Weizmann)" Date: Mon, 16 Nov 2020 10:53:06 +0200 Subject: [PATCH 23/50] Update on the docu of entanglement --- Documentation/doc.pdf | Bin 1597246 -> 1614941 bytes Documentation/renyi.tex | 18 +++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Documentation/doc.pdf b/Documentation/doc.pdf index acae44ff369ebd6f581c2f920e3fb82d10d652bf..e30f287ff04ceee31451cf45086b24139d09e307 100644 GIT binary patch delta 488470 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

Y7aejzGw%%@j(Zr$~CozQPQFV1`#}tc=I>3y> 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

5gReY${)qNF1iPUpD3J%c_ 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%0Ddk$LE`B<-Z*E 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
|f=8(s$a;A6*RH)nsZZQhX&9f$Co z+#<(4(g!%Bu>Oy+;n$^OKzUO(x4y#+?>^~5VXe9kh(7w>9R1$hoq$w^DP0%SBL+LV zpn$o(QGu!Ar0nqs<87|v@^CC;YKgnr`O)2= zYF9P4cmCN6x?1kH;g5g7G`xT1vXv$zK#&ztJK|lhWW>(aV<$Y$W91@K9)}Y(>2ZX8 z(;i1tBe+eihs%O0ImhWRKIwGC>;*B1o0P@4NS=W|ms^`hj{A)m$Nh$$1-@Pj;56_t zKm{R54;5f%hqZ5mmiYg;l-mlMP~BH7V1yAa`%yh>gtrme;4y!cJ^cUvVzDwNhQ<@c(dy{#NAAMi##4dd7;>)@V)pJQfg+fqbN(0_j>Eb??!zs~{bu8-Q{B(% zD5P_DyHMDnU?TxjT0auJ-p)Vy6~XZCYA3v0mtovye_J;7VZC)#EsEu>9}tWHOR%~T zM%Cf7^puvkvUPvC$pf=`%MadjQ^7*9EP_54SGgK`t2%fPUw%Sgw5iG_`l9kM@JbS^ zF}OEmwJ*w`C#pA_zFP|pss)g2Z|;C)C+8tL=dnMAhc;C8mNhobFa68s&HmY@+V(tM zm8!n^(jgU#cE9N^!BP=*kV@EIdkil-r%161v}@~C6|{c^UhLzg+&I?P0b!f5sOWzc zii)WCV3=Ot8pa%3zi1tX@0(4S9#p+*!>FhSJx91gyWZBj zvfCXlIe06?a^tt+7#`k*|7WTN{&`6i!*w%=$f*#ngOA#93_ypQ`{??~e*rg#y6KZ~ z+!F#bFq0t$CzB8<3<5GWmytCKDt}sCZ(F$$eb=wxWBWppGaPaT2o}h0>ZCvm1nWGs z4fa8C)YeEUZDkqA{`;P}k{w;kx>vTen=N4DerQMzhjR{RhF7zO6qGn*Zn&0^HRCFQ zsNz}!wH#OjXMb#gtBY$WNpQ7L#Gg|rCKE*$O-s;h!5Hs3hn%Y6hC-&KxPS41ir-ks z#fK^>WWjh^AS?~73WRI+HxRBhO|(F*mP+tnT0wtBaAS;aDinr#3N6hL)9}YR1rwaf7$opnOhH7!#H3rp5wDHYfpeOMwj)(-47c7oPTlC@Ka%Qj76#f zt4aOT&8KOK8=t13Rm1OYpz01`SkdaLSb_qbPZ@r)CKF3=Ho_zfj?uW2 zvC!O=EGOJx+6Glxh5Zfx4SL{)Lu<+3pq0n^*#ZT>8I(N>7S=RywBakWcuU$Y8~EZ;#lAoaQX;S0Zb|S+GeW} z3j?{A;l+zEy$sXW%XiB#eHH%j=AX;u8pF*a|1o^`-2{KG$bYNwUdem^F--sV_kX~{ zV*)BQX>=!A+8DSUH&|~ng`yrc{^LL z=c`4a&EucGtbbo$u4n6c*z`G>UMv^uZWS-!pQY7}+yy+XXu5j?nL3KO73lJetcGm`&q5BSiExH%$u(N%Dm8)%f zgB7N4SIeu*Ih+?$e{~V2@8)0D;oh1XJiML#Yd(Rk7JuvcVto^w($U<#{$_c*x|-i~ zRNuY&>-^*O?EB@H(BVW(BEdvpi>L+>Di_prphYo2s7~FRySIKv!&6T#-jpZI_ z^jw5eYtaaF!zB_ph}@yU7T}tgTYeOw^Z(w?*4N8LB#7){^fXnNU>o-uNwNCI!y2=% zZsjOd$A45IIiD)j80Z6_s>T8mCAC<=`=sEnOpmH^bNk^2ja?aw`Fy%$rI_Fhxq<1- zBOU{%B9O2gL2QrevYvhTJnt*vGyvW|nm>1C?^v#aUxeDQaE6V%XKbU1`#m}zNx5=lzlBgtY0oQDQ*o9$B&ZD290f4mbgVvy%@qaCcN!9tMghOmPJw*3(~TjojBWX z!)xNSMB_2yalzl=P;!Uyp37d9_SmbY6MxxDHu`x+e$J3iz)nbbE7e$G9E5ezkk?f< z-VP>P>K&YxY_|U&Y0oACdJEMKqz%2A+f7<0ijv> z$e4!Dw{KHo#4-r2Y82RnI$%+NU7{S`wcp%+y1n`L^?zno&lp00oxJ>erwf4HsWz<2 z>(%_1`O5Yvt34rtX#1OY!{8=#lz(hN%=2h{Yge`)aq(gTRfHyFBf{IvFLQ~djA&fo zQ(bD5U?}@t(c3_raFF==Tz7!po=al7A5Q40;Y2$tS!F6Qr-F#HBdJ_Gt*>3Jv2c50 zj^VDNPuRP)S7Y@;2Ut@%dbxdAIG5_VJb&r(vX>1D z-&YhUwlb#0wsxEWNJ%s{KY=k?SH;!L-=cbZWRc-uaL|M7Q3c!Qg3R_oW+#KpP6OG4 zT@TxBGx=J6Wl$)5e5m}o*==U4kJpR&>LJMN2_Ul`$l%?6+H@#Dwnt7q#7mNomH2jr zGg%jU!%t!x6YdJH?2ZU~Jb$+9_0#|&yLuon-?AL1GkNWVZCIEECA?;pAR1k+@5U4R+A6HwkPUk%zun5yaJI)d06-! z`LyCFA=M(nWM-CPF za1|LAW5{s(tl@s}a9 z0}}%|Gd7oD3kDMcH#V0*<^w9Xi(CN{0Rft~pIreN0Tm2H%BCX8L@>_jxK5hCLjV;& zA4q4n&Rzi@1%FV(oo0tik?#YU0CLNc#QOd$k*9%5-j#JvS#o^o2+5Q^mpC=?FHhdax=K&NKLwsHib^7Vou z0OOQ#sYIKJBBC{rOA6B&rZO`>(q&dq)eAgVa?|+?R2G-mpq~<#TxQW~VQ~e$WoDkg zFRzvoxbb>I7U0ajA+Y8S*~|{h3BLkp9>USPvR?`ZG-)gatOydmUNC*awA51x$7GR; zG+HOfM!%XY5E_=cV`InLr+P6&G{+{Xq2SbMD1R}#M=EQAM3^Cq$Tz(~tUC z`jHRQ&t-rl7_2ATeZ6e&4C&<|M)JthO9oL{RFLJ=~4LEu{1(6c79o|WeP-(WOyz?){!qynwC;kz!Z`mRug z7JonuEdYJsZr4lqxbyeZ;qL)=FF_;^lTo<;u~a4L`o}P9gG#PkvqJ3=iRl7XqOW~> zbd5ia_jynE1)jqH$K}WF&jq5O4UhNxKp&W-ab1E(=Wpu6M77`RtB)*zkp@viRs1z4QOyD=my>4!Ndh!5m)>UqXqRbc0V<5xTOv74Ni(y% z_5t@rd=;D3^{(n_<;hKwC!fE_lRRVEY6(YfH8)9%52iQ2dJN=`FBm>ZSYlO{iy|>b zWLDW^xxrDAqR6z;2`e&%qg2WDi+}%m6e5H=gCm3E?=N3`@>-gNzgV!etC!uy_m_X%5B+##-Ul83^Kw8+ zDe}x%J*A~lnPuXA(ozbO70OJgxx3obT~{~TXVPsn$AP$LRp1oA{XS1t@PF)&@UAFq z^439a63JD@3Ipfsu)PM z>B>z-&${ZaY|9?!>z-UU?Fd$;_4b0>w6EH7iC~{1T@t25COJ4Q}fV~e~K#q>#l1DI>85bah1n^lDTR3G#4$*xX8Hfo`1>@$B8v^^Y2V;o> zFryJnX9k!KSix6^1QMf9E{cpf8OcQMN zb;dxw7?=*JMzrU}2r-_?VodulB8b^cAo@Tukhu|FqtQerEK3GZpG9#KNZLJ4Z8{ zC)jyP@xf*6|B6!Zqe>wm!V*J-Gcv3K{pmG5SvC%O6+%&OqOZ!XTG443WB+dTJtKMb6H)El0Sda{1o4G#;01cmWuHJDH&dn0F)qkf~ufJHXzjM?7P2 z$3W0LMR-i3BEyqY80Rn+h?4RKiMy^&~6_AJ6Y4R;W$wTrD5SAZu??}!q z7=+%C@ar7WvxAR5aC{1=DP8@d@Sg8>#?wNs0;v)j=A-Ui6@uKm31nYD1pL`dB7`=2 z06aG-s3l(R;aPx4AwO`DH4K~NH!A5NG*q1DM0UHyi zQA24nZpUe%jiiMf@G?G${-&2&c>y(l#)(~M%w$!@wD~pd_vmxvWb<*UWh!(|7Y8^+ zYb0O+t*?>jb7~}_I3no_%&WzyNb=XnM{@{R>{E**W5-I`4q;qw&2P#1sNyW=!^Y0% zizw+OM?;kH02K?C;fp{@WI8jCVdLct8zti>*$5GluzbwNA0pHcz(;wKj~Y;a`t9*i z@H5z`B_FZzGD3QpxqRcm#UEl?yMS;4WCxT(DoE({uNrJH$kuZ(SBil=z=+QZHkg9B z8=k1#fRA9Of(?k>3lKs!C=IhBvak)xCHZ@=MUTnmOYXw?>n8=IQw@OU=Qwm8m7%e{wV-VSpmV~S zsBA1iwjmV5R2i-1tTdwaQ%)L<;Ujj!%LnvH8X-T`#dsk}O}t70VHpg6#-;u60%^q) zW-wijVIZ{&G`8l5*g`sQ)Hz~%4*n*yBOm+k6utYZCOi%P=jn`ryaQJog8~8UQ^vrxq7G@Fb;%J5ZhT+41{hP z6ulyZAku;$igGMd_-FqU3-JKwL>6En58WzEFqg)I5`bFyZWR~OjWOj0B29n`ue*=@ z^3R7~;nu=S{HfoO91=$GFQf1LE26s#CLvvSD=#+RmufkCj~N1gwynSfU1UC=BIHil z76ULqOZnmKI7`6wUVt-47PN5rT|lHIB!tNJNO8($(yDW7Q|7GNl=<+rDRFjf${eXp zVK7jLQEjS-)TR`7`4=^UY$xqQuKr}O{$zap>0^R;J19oomecZ-?>cJz0?=+r3qHfT z)os)Ex425`F1Jm8Pi;(;_n}8-(e|Wy2XCJ4;CWcf*hcAy@htk8U{<1KCF`<@^Ifuh zej>BL2va{clZn?->~#HdqV!Dct8X90RTRV*Qn_=wcg|tiAjvUD$_K!kTvA_)2MY`D zT)SqoGm7YYKWLue2TzDl?(EiS8RBTp9xFr7N#%cAGK4UH;&B~d=B#wooJf@UP=w;v zGzVieG^Qqx^?z|^o5#!R*E?$Kl<8gD++DD=yeSXs=U@`Ip^>Rvb)iK}GRz%Cro_>O zC2;(cFz%ZO?M)`B|6t#(^6Cz7xe$5!b8NC=uU3cdmY6T4W+=|Gf}2?3N*^s;}_ch=glks*irrCL&K3L&A z+3AB0amc?nQPX{p7Frh3m@;8zCC*F0#5+j9q|3#BVNk;#Gz2j%M-4%Z=sIT+IGO+6c3`hatk!RY<$-sg!5hXVmFr)e7 zZM@2Vqn(_5n0Yf9Lfc&WK`w5A(${>B=-uUXaLy?=ac@V}3A)jdU zVx7ceC08?C;&Ly@Gr1FYbyKX(GCfG4Sgam@l|z<1N}*(tuFKBvO7X2taPPWVuU%u* zTen%#-)x%=onbfBVuiq1m)fo>s!7o()W__4u3AXQ`dxb!QZm}D(zN&32krK_hyxz} znQwb zeDcx*fwPAmDMDHEv}#+o3r7P67eptG`x6|-_2Ny{ZtA`+w*=kQ+hs*nIE`r#+K|0A z&uhJ$(fY|s6KcJeyng{Ge>80Bs9^&+Q-Y_7zeDua`{=bRga}+m(NjcCi5kH14YQ3{+v`-sUcB#nUP<3{Ki| z=}tB6+|v%Va3p2#f9^LMhhUFZuU-;3;M3MWqX^0z>_*)Y5wMy&T>FA^z4ue=-SQvz z(ZmfjitmZF#La-~b+D~~ixWGNHl4ymyrdQd6|#mrziwKBcKZdHA`1$~ud3^e&c5{) z5jS&NzpLAwe)aha7(v;Q#e_TGqeT}seG`<573mI~LrdfJf48n-7S779+imVV-f;a3 z9p2v7`(0*;k%wMZE$*arat@ay80*^OP1_)u3Y*fV!hP5j32x%BDbjBR2P04eOub`t zq)oK`osMnWwr$&(*tRoCI_4x3cWm2sCdS0JGqEO^;LUT+I{)>4t9{*d*XsK9m#*q- z?;T<*`?TJdvNhyk<}Brj{)AE)u)JKel<`Pg2@{k1T$cX_!^lb%Xb15 z(gd#`dW@+cYtVh9Vh0?L-Iy2#V-)x!pjN-B4oMA1eWLP|+nsQx72vL6dI10gblPpn zuWT@E&e+cbXALQlLjFD|ciR#Gv{QG)EKvl?QHgC8zluOhd|l?Q#$@^Fw>}}*U5!NQ zN;2cH@xfbKIw{^f`gA(_@vr^!(*&=TUD-;uJTqE2>!jE5r~*2lDt9n?6JUA zGH89&toJ>DDI6ee@W)%v(lf?6Z+)WkawU~5t{uAnx!|th;)GS}D@1X?KS{=2-mdy; zH#PGe7~EF%8quAwvX-+UH$|vVk%Xi%iA+qZ??W?=5*P z*}-Tq2D8{ps@$vEHfmH+K?^8+DTLkmx=_D2>A7+r+MG!IWpp$uM!#2ecIksASsQi0 zlf1jx61=-NdB3}<;3)B^r|n+Zd*nI!T)veG%#;0))?o%>hEUjjK<5Y+Mph|Z3JHmF ziWxU6*w~3+5@~g!n9%mzns>s&=jM8G!wPwFGmkSE#>>F+LPT17pO;<_PM51N)^%F- zoEu6~piIbt$olmJ{1a^z;2Bd@{vkVv-u&LEyxSY)>TW2@>=GMSyNPhQD_zrmGO0*J z*6~2#1)BlR!F;nMNnVG0-7yi(>%AxYUPHd}+x;^8tmM}t zkkrj#N^4vN!I1sP3u_T>6NPYeo9)gTsHO35ywfqiM2fI{{*4Y_{$!U@@jO*nIY=t< z^e?;MZvq#j4RQ-ol?2!+74q-rm7|BjNjem1`F5`#@Q9#3=*S+Mmuk*RbB6&$t zb@Pmet*z%-`z8%jYIDg-tHkt%j?Tic8GqMylG8Z8{=Qjr8P&%P5Q9Pab_2&p$4{pl znW+w*%47ViC%xsZqpmAQ@T;>GkE0u_t>3e#;sy+l@l;=%3{W+-JqMuJhR7FOlJp>QpeCDZ-IXNIjq#5(VJmh0wD8fW)jM7$&*PK4jap;dSe+F0 zwJ|Le#s=RPcw-x{l?}qDsE>1)SGYOe@UCTV zAMwyi8Yl;7;F`;CCq&7Bj}_B->yo4R49SGLBvN2*Hbn?Sc0OZ^nYQghjnUhITo|b^ ze2(mfTI`+#c@T+_I4UeDogvM+Okgi9*?+~}Le_pJUvvWGOkg+8JH`;Av?|kmSi_y! ze5_M}syIDR)AJ?mNdk%07W~ukG4Z54a3~^CL@~%1H><3BRg5pXXZ&=c7X<`8Ltos6rO|cNYcB*Nd zMN%yW%g^v6u&Lo_9^e*84|+A&DxzEhC}Tf>soofSukB}EY3Evl+s~;mETH?1%Be>N zG5V0ZhAp4MX560g8LRuss}IlqlE?eo>FJ}5uHmrAKhsD6WAQ1^EFCUX#DwO@D>rOl znTTI=w$U&N_T-=Aq0HRPpa5OV5K)#YOC&C5xGi}uKcPJ4DnbQQ!5gq&2)1|E^JP@P zA+&x2+l3SRYNLAg8a~I!iSDktRAdo9d!=T(1npn)aWZyHKik&Nz^M2q6^L+j;J3yG z`>Rp&PoaHrO^@1l_fxKUYyUR4H|B$}Ach)qM{h*Lx2lDVunSG;{`l8BGezVVdxL5t z%c|e@YLChu*K!Z`Gt73doz(vpCa#|o$i8=icxF+tDsL!!#J36%I3HKVEAlhVR1*xg zmC4Ww0cd$uEH+jCCf_&zsE=}mdZ+!ZnAarDO$~6l@rU};P{~DFxSB^ z;8w=_qv*rMair`f%D<9(OXFJ&yi6fLm%xK8kT5H!X_~2Z@~g^=u<(=+ftb~NrM#lp zQl)yb$hc{{<@y}2;13*~K!hB1e$3hi|>q%M2{=iWv;UR2tpIiZbYk<2Od)q18R zA1`SiP75cl?Nld{_=}~w0Agj^`m-6s+g_;M>?p(AMClu1%gWoj{!iy1d~qC;O+BOJ`hf4F$_gVG(?mRHl$@Mw!IO<)duI|7O=XTBSFJX zu)0Bfm=1Z^>?yp>B^>Cv(X`-dUw>B9ESco*(7z4 zn^I59VJArCd+bNo`?Ft@UF3sZ^J#9uywFt~qkC}qh~3(tx@pmd#9WchCtDdMJST<) z@1Y$5RaKVg;Nc$GW~&SrAUO1%tOCoa+{ubxzWW!MV)9vfY3;qGuFypos~wM*IASvf z0Xo4he#-jAFJ)OEl+W3ss6>IcHSLtDgqYD}%j#n4&55rhWHSXVM#U~$x39;QDNF^7 zX@QI=@^biAN)0;-_#7A(1TDndMzN-LMkF_b*}hoN*g7?R>J6|&y<1MY!J#p)5u-*L zMYZzZhtW&Il9uc1&WRPufi=n5m8G}Nd_QKGJmY;kcunnaUB($bo3C4B$f_G4x`iosa(!=D)BZ@ zJk`W}KftSjd#se>tZRo+3;pJ7JcZoH(h*>y9Hczt;!cvtlW}9F9f^yEUi+dx-|yjw`FSF;u~;lyy2 z5z;71^Ww@O&4-7ZA=QBY7tRbse;2~1vi%+~{D7=8HIp6Pe^M}^2*Z;MW7WsWdD${} ztb>gGtNv|OmwLI99%;X5n4sg~ZGhK`jQ4_QXz*wcCo15lOG$u)99yAhowmNpMBCb8 zqv5BjbGyKg*0Xa-ZX!W?y^4^{B@Z7KIHqK>Tz~LG# z>%-P+2$C=7_2|+dk@A!75ozvc2&O_6LaBrU(pVdDwodb#=sM3*Y<|sf64B`c&ro#C zZ#*6hy<$?9y;3G!8{UsD`~~;o7xtXEGEa)*mBsM#iajKe^(&*mYzVsF->+Ztc2qw` z|Dd+QBh1pZO_A%S(?B}I;wUV+ygfnAZV#Gt_J}WMbLdMCgv|HX9&i3j_}CM~#JUjq zq(IL4#M6aou5)>eJ_K^FGKQxE=^ezc`>p7RTh+a-8@H7{PKdh;%=;aaq3obL|+4WEOgQpOR{YBj2w#>jI&ckK1D4U|e%?B6H$6}-KZfXS`@f-c^n0-;bqQ-KfnO6YNmF4? zzwNdPT#~n`_)beDfO8f24>K*X2P=-Z;#Vb_KdWzW{HBkZ_WjkALT zp1mt?yQLmf;nRM$3ek*@!J5b*w5#Erk;bS8PoIWQ0Aw;wrttsV41jJCp|K$Ncz8j8 z0&qH@p4?YPHdgPs&MvI>FKj;vo}@c5ImSt59pAZMe6sRbvLO;FVrGazNi-k#z6$18 zBluD!2y>@Mb;iK!?+D4K-13Faxs+<;7JoD#RE{)`3ZY@razua=Q#-k`gi#iUHL@Pq zd}ZNn!s~giAlgYuy9HUR!F^^a5C6Lb8n{7Vp@NUR&&T`mcoWWu6g!$;()j5yuBALJ z9v_O3x)e|3spp%W@kjd{eeH%*(~{AsNbb#JU{k8A{?*3xM%Hyijfi17OTlQJGj$~= zKiW*0f+0Uc_oA^nNLnCKuWk0&)0=stwVEZbqHPV2#zoFCLdO4{I~tkwFH!YU#?Niw z!j!v33KqNjY;B>A$G%a}PBF`urXmn0D1( zHPKbOiK7yVyQYW;>>Hd5Bj@8tb*)Su^{ zEUTe)bi|Da0>$0k3cT(8vk7f?A@W`g5f~Hb-onDu0*7g{TP)|KJg!X1C#1O)mrsV| zg9hvr1;*sBY9b(k<d9&T#~L>a6-xYv`cEX7ks# z<#K|9gf%1YLbcUft9NwBCTDnuQ_6Mk_||Xj0Pd!#A_mCptU?RF77Aqp#Igury$w)} zg=Wamh5nI1y82Zv^(aM_;{|qOtU7xg+JSc+x;w$qrxD5TcbAq6P4rC>T_EHpcdEu} zkXl9=B5E=ifu$W>0^nA90&hPqEzAe!M#5%PF4+I-H2wqfcAg;7=Uw(!XwmGNq(}1e zDl}V&zg;`K!|#STp&yRuz+24DuPR(@Fg$dU;L!{%s<0GB)>e{&y`=kRzTbrG(qa}7 ztM7JNAikMi=EpL*5O6@F5;e#_)4GZXZgimovMW6(T~2%L?f5xGQw5NHLGB31JTbU_ zwTmTl5b|v}{CsUTPLd)p`6aYN>{ZTZVGO!cl=D1+P|@@V?S;XPVNiHAB)$zJC=t|2Uqs zY)%Nq2&Sn8!N^%`6If_JA#`Uc4t^v-a$O#z${W&uQ?M5=!3JK(^gUOlKkZv?y*W>W zK}_9Bnl8~9QNYh>;!e6a*97CP3X!=#+|`*xmk6{xT>Psoa!LJ2v#UiyLB-F{se-mm z6v`Aqb17T_XN>0NS&m+n*P?PJEp2bek_#z)kqzBPmOiZtTflIJ$V9a*#W`u4nv+*i zbqH#g`fS1S26VH66PokhyieY3>5+xs;HXDbUkjSw(|E z9x3_#f|LR|^?Ak?OiZ>ugs8|{)JFC1djkbDJ}zS>tHApF^Oq->EyJO)CRj)Fw zAL3SI8uzl&-s(0yn}nBgUGC**!Wzb1qJv;W_J?oOG9NBuB!S~3+VQTg`DiN(uzJlz z{sQyBja04S>HVh!mIuUqRy*+zzeyFa&%3r>)7hxT}=-N!^LX+iag^<1lxOim>&r zE10AHJ4*q;(^Ao6c|Q?XmG3iEmBz@LK)i26ZM3z8xgi96sy?pFw7pbDC^(+5LyAd9 ztteRGkwqehp>s(CS}rLq?I#@t(>3k{jE)F`WN*6ioAhxw&CP8= zLl-#d>r7@IRHWAu*YzM{zp2*MWNoK0W1bOWccWLb>l>M-ZN5L(#D`w{-C)@oqRs%W zY~ik2%XCVltBGp z2a15SB3rT)GM)zh^8PfSV0NrK@gjbC>R?&&uH;It8T}@))vSq8Z+>>zb}o(XkG8Uh z$Ej>c%e;Pfww`vQ8t>#?|Y`$v@L_Hpua~!8Lw=w6>v1 zuZ9MZ5SF!wG_V{f6%gY0Dz^Eg-`S36D;2@k>`j*y?%#rJzr zVo5y(+6aaB&cDZ?39tIOSw0|FSfKsk2++Dh^(UImP-=RH(mqaSx@<;mal=1u3?BP& z89lWsYC#=GR%RpdpF38&*v!ycmM=Jk3#foa`*gy{zjB%11> z7)-kx1$%ZCnvO1|4&2vd@A<7HQx7u3eP7Y(yk*?AlC>86D9gpZ4YTjy6Tgnd)#1lHi~Lfd6^{ILIk%c@DiT-2o{{l7YtNyd0(rP z?{Nu4@AVH}<@M1Eh#*H?CLmDQjLHd0vqOq(eG`gMaG2qRHdfDR*x>r>9P6Y`PkUzPDP zViZ~KxZGs&<28K0?~C}&0+8|iFr-g-=SsaLq}rofUgJJ4UZ?MN{QC<+AZ0Q|k;M^u zR>4tWqTi=&TRL+>GJXQ1;ve~&XwRoz865+=zLifG%QC78ehj39w_oW0IQQWHplW2q zgU{;xsf}2}8b}9l)Ca2nfV!2O3%_36TQfkQm)4kf#|zIt^HvJjIJCYxvVqfoX{m}f zyQ}Ox$pGGrB~px<#x{SF!?3Ob)~*Wr`|6m7gKsTcWT!%221ynvTM<6z>=?C8wDLbO z1b=)CpwQQun+NeXmyJNyp{ONHZ9b4RMQ7<*F$K~#%;#0SC345_OV})puH70wg9xex zcbqX0kv z;QC)9uw)@X0sJfYA0zN`F+du?4I(N5C;@od>`MUfK_E$La12nbD0mkriv}FCEkF!h z5&*KH1;+%{(SUb?YU%zHX~Ee5AP9!9A%P^gC;%kO2#(d}BK4nY$@HZfFoMGaKyJ)m zOZhT^zks4yz%kmwnZY3eAYaxmF`ET^3zWh3CH`OqM*@Iy*}vAWVFSMbg>Zmlfg0Jt z=Rh%>UlY?fz#jnY|C7bg_Nf9+0f6A+{|}->zOVhW{f9{L zi&Sv`*XDTm!7ZRcc4Gg_sT(vX{v`(f4<{JOui+ORRscv}>I=yi9Wel?Q2I;#qQedV z4a$7I^|faz(7H7EDQHIaEBqq#3_6tin)5{n0svZ+|AO&FXcP3H@FjlDMg)Lf6u-o3 zHt<^zh4Pn(qy&xwNK^UJc$LA&K<6r7>tLvWuY%N*kTL%wMGg4+lK=m0pW7_dzVHDo zK~d`9y+BZ!%sY2{5<{$70=9I=6azWU!fZ4x7jX%VyVz&LqQ&f!c+{A$2;K>Mtddmk zBqxj_bk8@(`~d1dFF=~|9Z@WI)KU+t>O)tcay6{Lv`oOWuYo!iM~SN#SILYd@rxGK z6Rm#(dj{6u8lhv1cwbm$Q$wgv)*s1mGwKW?=fHeq@SLo|W_EX0Ru)ZZVJZC|)@#DK-Oaw7I1yC3|c@c~@iTGY3uT2-7-r{a-OYBPLW^ zijwXb68q`e$FnPDh4>0oAA)p(v^fis(e#I*gOhSz$7_-&Bxr^J!^k?yxg+(!^wY1F z!oUMvkI;Kf5@U~ni|JoHyFI@xpS9Os+Bky6lU(ZH8|MFv_RKpVOa$@pM=iBSzJ-Z_ zEgw>k0k*HH;lq>&Hp4VtG`1wo$nOk_#;)B{+$I`e-iv(~m0rWMva5O~A$bu&CE30P z=XrDHLWO_fPsL7t@7HT0bAjvU9@fX4ECF9n?sX*6a~{qYO|n*X5wBoX*z@puv^CsF zh3|sWm7-;T_fad2h;ge%#TAOa6Wa_3!7+_lOCfx~*$liF&kbrwDBl*?h$%olYBA*h zotk(H{h?x>l|BgIOt+5WA>=3yh&fuzqgQXo8B>;|wmN3G(7(E?@#RFc+D{d>8UuQ% zAgmpKO8gb!wD|0Kk6_d6^}%j4RSY)#Sojy0R}uq%7$7z|X2;My`q@1@0?VqG@V9FU z@sF2MDum<8(b2H<(K&URX#0N9hicrcRgYslQOi;1iCd@viLLJMI_L9`Op((_JQ|Ib zqrl%eJdQ0j5*<;a-N(O2e~Js0I=%vX?Ovv9*SRAJN^7eA-A>-M9{>sp=bD4dgY)ov zIoLahg`NH-!EI{*q|WP$DvAEmuMm05s6V`dw7&O;Y;=~9d3WPu2;zAzaPu5#m6uyI zp|4sS^GSt-Qm9c9%$9)tJWLR(~JTw(cl*SNhRlIB{qUCZ;PafbqIEoxY~ zv^54X*$fR4^}#j2h=JSq-`-iic>tG8E<792rNZDSW7K^6%;17*M$#MFB`>oYFN+{g zZy(Rvg+!M2bn1-X5?oJl2fQl4akKi$-fK(rT}+5PQp?U?y!A(3Wu<#e=0 zgL@l4F_r3;>k1%)!|H(_J}5x$RBQ5Ri8n2Eoxp|q2*|nDN04QgbGt7=OvvNXWBFa+ ztSE`+APRqQ{A9jvTD6_AXP&w<@nIzBAGPN3Y+)y1#qm}1_Wi0@^r=lJvg4L20OKR{WZ!+E5;}hxMm@RHT5PhGf7K407oUW14(4R2J4r z#AU3&DEo>U3#gI=`0<87*6;^k(UNb+C}w`i9UO=FNn_!(v^m@Wc0`wdu@>`=4z#@j zmuU(!PhgDU(-bK`aF2}9cij>oNz1>V@V}!^e^XdpqiBfdzPXmunx`g=Q8HD_4UuA{ zCW-FssckD>hO`4_AF@iuHTAihAu(daYYfVf=Y|T5kRn6c5N2|>8i67+!MQ~)&&`J& z#Tq&~9TWnC6TnFPb|X=dZV)1^;su0f3sBnI?EjXXcG-TED)G&rmHuEDH0$cBtwWaM zYF0I6^$o=oZ3hO)b(EzqcGTWaacc>dDXsmq(};Z&HIW7i;EZH7v!*m5l)Y+KiYap; zcPN(OjaW=fAyvxaVb0Z*Mn}Z0TIqYzeel5$|D13mIX?`j)P7IY zYkAcSSPt>3H@BfE6z)<^YZyZ9%h{Xf_>fF@Y%N6)ecSFQI)7n;lw3w%T~hZ^_MxWS zzEf!+F-jQ)+HV2}Wkv)nc4EKpv~}^Gz;&&ZXRu*lJRGJ3*8!SV4BtQg!@{n{l4ygm zQ}LwDy!A=4OLww3`$1EYb-z*nmD&nqo~SKt5Q~@NyRB7 z4dyBk$C}K2-{W{mH(cQgRe3w-oZR`!6{j^ly}o_)w|cps4Kb+V{^+L&jdB^JApG$x zI4bSRq&g^=8o7iSDM1BfSz1#2Vg|oDYGxjVoN;3}Q`GSzv1!bk@{Nh=CL`$IL&o?c zVOrHciZLLy1V!HHz&tJpB&n5h?4Tb9|_jcclUwp zJgYyuC#*Da?&*^pw#8&3q+@HwXrkj%`1$R7)Ei7@X6$>Bc=%j&mGXJt&^EXaLc0E} zK43}dmlT?7V;=D`4u-qK;7HJg=R0)qCDG`3rF}QiBsx)p+ZEFh{E@YnTtP>(XR=p!5D8U$l!TFr^*=hXFsf|KP7TcDPRnRE5lO_R07)Tb> zA7pxF8IYa*w_YE1OY;=bnrScn7~09ncp5n|ijT8!` z>XO?(EEI5FlKcQT2jc+znmhkMYBaia*Cd-1znI-QC0JsLe?Fsr!@6Frv1Os#R5s(k z&;AzB|16;2@zm>HW!Nknc~jz*bv-ZLfIW(vxv(nBt=_K)e#UPHW$oDPIt z)(*N3zl;;d>&4DT0aG%uHjwS($I$+~f4`KkdlbvR-rh9~f;GZf5v!T|th4^yKNoW} z_A~F)OJar%vh_>*#Nm`dslQvy88020)owlD<8}v6y}N3hUVUUO1_2kyF<%+(Me|lu z8VUNd9)DJU)z%8n)<$x`2@lQP%CbfuG*7SEoed0F~!6En}|nQ_#rK}_qQMynkQAq_^@FZguf7( z8Rf&-_ck412RVVe!iBI}oW1e5T0EW&^poyAQ_yF1KW8Y)Ut^cY`h$eY>z$y6r zdz#P+R%_5Lr0i=)#x%(X*EOI<;8+i${>|2+Y+=C>A#_%_oB#wdQ{UZlFeDxdEy|W` zhUFp1zQQPAaQIzK&hhZIO1FJ=gQp`w4*g8)49qb%>lt+E%)$Q@RLVlEN6$cf5d3h( zUuimi1!O2#M>r3m1K-(Pr!}i~@we@fP6kl8^bdgOZ#%eQ2%UGjqPCCe2@@<=x1@G~ zFxAT2fP;V0Y4R~p$CnBwc5a9bH_^t_{`)6zm1|VwjBslHySMZPNU86sLOY|1xzJe1 z$JxK_n2MD1nh-C3DpV7kh{wgFSRRA&Ne@3ExQcTf{@0(&!2xo8!=XXq;)G{Wv~;re zup#B(1&O)i&;u{^9i0i=&^~I72b^2xtU%W+5oo0G6r+g>N#8EA>WW!M+H;D*@zGeJk;>S@qiuX>z(uG1OJqw{g$v|}Mr z89Mlb^pE7iaF%6zlKoMa-Q-CIAd;|}>jBT|tTw1*tQ!f1q)Xf(OmGZMY~U*WCl9=qB1CcXSv*C}tKcPyZbcEd~;cz&mNnvroWtv^o zTq)sMiZ<2I#c#iTmlea`6T{ax@t!~I3L>k>7gHjmHbNRTmljNnnU@=_D3ehB0fRaNIdhxX0u)5=sIW0I4aNRgJ` zbR*IX>2E`K5eC|iUn?STu}jU^b0nq{O{ZAze+LCyIN1q1-2b8o6NI0dcn-=KL&k!j z$&ay9SW0DXJiE81^2y!y(C)mw%it!`CEYeRkq0F%#4ap^=CJg2qwBtC>P`Wq=*wLtOwFxSf_dFDvug-Rl=P*cl>pQzxPz9wE%5gu2Q<1&eR1187BQawO~qbm0+NoJV!i;XdT*m4Ocb7a=D0T<--s+;vscK z=zfSjnPit0AQ{jaPg_UUotLbR&gWglxYd2sV+!#+3FodHj(7RNbZ0W3pSh8ZeFysY zY6KdySmE3c`6ULZ68q_qC{@xlp_t`$yNqMuGlp=`neq2KED_Rz)e_v)l`i11ULo)c zCoTR)?2KndKJV~x3H0dJ>3b2!(#ED2f+V}|{5Ep~J!I(3o+Vt8LM#{nsieS~3ri48 z|DjeXBKrc<-;+%g0B_-Jl#{n2vkO%B?Cei6z6`i8T@4@Ut|`@+Z}eu@gMHhXeW1B* z^Xu(j9K@U$e7C>uoejUX!4gT7yfwS)#ZG7ccu;+FGh$M~_N3ZwGkzV!yxU9P(QL@M zdmP@dymC_&yQRJ#zB^C0Lx$1RErZ`zY=PpE`eBIH-Snv9bmE-G?vsiWZPyzOZ;r8BK7o6LGWc&{ z_TaUFesA|N>50f-%VFTXe7?dRc%<3n6|fud zBZL+uApW6M>~&KFDC)P$LOcjc#dV9HX*f}O-3R(%w0KRwo%zr`r+|oJkSF8x*A4|6 z)6Q?WG5g#h23S_7YzD2_iI}p-7Leg$Y9?rJ!{yOX-ni{duu1+=(!qiD=)SOiXjiL} zGZqbGjg0MGxcj!tkf0ExJa7*@QoCV#@gHdS$oiWxolmyP@`< zQZ^~+c44F$hEaH6{0tgXdA#tetJNL3teVKoe78&{W(X=ht?5yFF53LG2)m7DT?wq> zR>4a3;Pn#JGkdhCl7ku37BGE0dam6i>LsGm)gqoYA1#P$ufVlE1QS^vZU+I_NcdkC zbo$-Js^k>Tjup5g7U7E)y>=<`u0qA^fx%o;7+& z3~Nu%4r%>49@=zLT;klp&i?s9N{1VJ?qf7nHps}nfF%S?+tdI1)I$p>yHdZ6~IklW^dJwO6hRp#|`VX?q_-M{Xo~*@XMJ4 z-7{{4##TEN0ct5>Zuau^xrW%E-cH?I)Z%Z9m48l8l7VY_J?Kpj!FS3pTU8+Onr_D@ zwqGa72M73Kq(vhEmXk%V9(t}>j3Ah-fTGDZE@9US!R(wIt=Xw-Y6cbI+`PqwyY5^SE1B7nyPZdW?U_=~j<=O+gWRd} zPC@Br10XR4J|j*t$`SZxP8ydrU0Jd%Qk&}XXLq@>DZ$a6MWBzXm;X25DV@)~A%(~> z@$cUWu~j~Xn0?}&@r^KKld#0v}%qJphh(#rl3_^c34CBzyWIyR)aqhlwxD z4V$dox1m)})^l?HgmMPA-&NlA;0aw?ZF6YHTQ)0-RqQf75&pG99!XdlS9Cbb;S#HJ zoG_&5njIF8K0%N)R4{RAm8zgm6)#pp6))_V!TTz$%IL|}SMVNp5O&vEN=jF=jfu%E z5(}J`pa_ggNFG_X_-b9+5YxMkiA*!ux%#dvBf=TMq=ZfeuB5I;rMDb~$lV+!Rg!g~ z<}5Kt&w#or<^V5dVUY?`&|*aubK8x)(zGx4e*188B-fM9c=eME8vv~3BJ1X2)F5AP zWCW0J&zrjE&K`$uZpt8;;$e~hlA^8tx@tOcf|Qu>TKod*+%K`s5D72XDY` zwaZdVu_G(Er9{A!j~<@&kMVF(TH2BzN!UE6b7@_qdsCpE zNPn?X3=aguFY@3rKz)zL60|Vn72-H`F_oM%v;(ReY32^1E*YKZ?5BPhw8Rn#!91-E zE)-d4z|~hMeuRm-_0wmpTDLGvjXW?AvQx%%p4beq-7^1uEh) z`_a4(7N`!oV`tyZfQ~ux&i36)T?trM%SNHwVHu}~6q9cB$Tj7k>$QUKE)3S?DWru= znPF2Hr0ylYtu;*PQl*9W-G;zK+| zaU5D8U`Hf%uzI?Z;5ig2G;U;3j#=c_N4y@xZI3Wtbm(lIF1 zraLPEOS4>>(oP zcf8pe&*vsHy`GNmW)}>9#~}2+z`s zKPV4#F}O>FGwPAV0*&Fax{s-qdl`J5Eb{3vHif(uhZt>R|H-`^?*)`n%{V8ftqL64 zJJFKyOj#JN())VcJ!MlE7PxQ4)tJT~9$Cg?3Zo@O3}j{H@gZMmSMaDnnNPg3)NogEsC8;A|QBZPOi?gpUE5_XW>$EXjcn!j>$7GaeOb``y07=^uK#;8g~f)<-7g>_H|1>^JRTzPwz-@1NEra z*=s=hB@d2vy}r^SvRehaQni;q%Q|x)@u>S>0EBiy z5@;}=$a2FfNAKH+_kqrl8NJ>^iaY;IORu~9g+A93e||+}YNaHHv}zJAb*t-gLAFexiS(UUA&Y6#KgGi%g6#V|;#wH}A-m*1|mLlb<@Xw^D^n z$3nDCw%1ic^iw%`Ah{;92e&^CPY4)GH&*WEz2Cyu@u-?y&37Nh<}76pTv_&HF{w1( zZEYw~hS&Ut+6I?FAMV?CFW8+!ZYwChtn(0cxlWb5qq*pm9Wq@VTsH>cMm_V7K&2iLK-PHw$*=hAlqT#gOH&Hj=3 z%|mb``Zcb_qnx-;Fe{BjVvrgWIL6oisk6P1Sl~RYpxY<}IuMf!I5H4YbU(3%Feyi| zRXyuM&>&SJ34&=3-I`W?kAnExv@f7*4oqr3fysKL!ax!g68}`XZ!QL>ORD?%L#jK9 zg1SXX+ zIQHbqcmE#!nzcqI?#n-IRU}{eFFRB2v$tJUXml88GV+srOj`K1)VaxN(W;4ZOFuH- z9}8?Y3TuTEoiGSxF32@PX+Q4tyH^L>NK9&3{ao#3h_T^RD6D{(&6C3dv24Lj|4z<) zK8a}yO(7jW?eZWnqC7gLof~^4<59;OFB{Jb89%Z-qd@Q5UP{YHT>^d#^!TeUXL_G# z)E3iQuPf-(AbgY867V8h#$bc3J06SXp!n&#>5WJ3 zoqVvxNQxh7q=ZoW+v{5MN0+_zvDdcSOs!3SA+e1ACDsP4aGg~ZYXIVBZH~q@m%i` zH`dY#M<_p+R^0yj;o5ET(CE||&{I`aU5rw%E5r2Nic(prKNpsy*Axx3rzt6&@?62;Se5{C-yrBP9zyuemz+$(?3z*sr~ z@1?lVTR^7a3e`@2OHthqFd;__YTYD)cA(4yVCNH46q&KZsTE?ZdQpaZ^h-=m%F^}V z#=Y`46PhP3Pq92vcW28>Oez5YjhR0|-wDD}*;IcD0975^Vs?-(3d)a-l5wv&l5v2EK zv2EM7ZQD*JnDEYX?t9KX^?vLRUHxBOwQJR0-TiCq#+Bi$%ga(Di4E{KvX(0DOGfFV z#Iu+7`tlg-)XhEgKTxNu%jNsaSJQHG{t?DZph!~&CfTjZRzYPDWJd}LZAl`j-{a6+ zoW=uX4^V6qfH2B^5e?;7{2L$PkRLkWvHha-xcDCZQ}3r zEg~GED7f8h&aGrc>;c=dc`Cx9hCN4f@jW^>XbA) zIolmcNA-N4~?h#m2-L70X$aVay%1=}?` z71Vw23qT=Z=`xwEJd~)cI!glkZlxH+g>>GlMvF}C!eNbz3o0Wk&Ld4&YhO!Ajfu~# zcqDGMCmrFuO^zgEL9W9Mh{59?Y&U@tR`BRP%!30axNWQ3O$c`Cd}9O& zH^8F%%8*ERZ#H9$D`xMMJ!qY6OhSz$zc7`ZDaW6R#6ZW2C}1z-y@4J{JdM4P`P-=R zNu9;4c@xzlrCMf7g>e32qOolk)F0WXRW!2@Rw<9pN#G{3zST~59ZWD5%-turF4=+4 ztpaya4gs{&wdztbzZjP{;04bG!V!!h5QxT;?0^#s+v+ZR%bFrPHQm6*+1Z)L+2sXCf#1`8A2VYo;DeY@6Xl$@(kVARzY^+ueiz>X5+Li~v@3 zBXq#{r8hh@pAyyQVvlhLyZA(jo0wlJWf%kz_G9h01TK6g5OWvGBcr_~CHhX>fgZ`l zTZOequ6Q@zR@#+9y)*AMWFlgziKv&!@xUp-xI@5g2-I}KmuoQxLUZRX$NptZ#k>;~JZ_kJ<)hzsbJ zBC??n)ajhmqQA3$E7mu?(Y3Mb0Uc{lP!hlF)J)YN?m6ZHm<7w&gESb`>5s#gOy}w< z-up@6h}M%Vvih-t>cY&n_=i>z(8EWVMOH{`pX4&7JT*V=n-q1UKfSHdPrl#dxsMvV zkq9{sl%qn-A8MM2*J|E&8Kd|*BqFpG`@;bpxEWc z!kF*0d|kXoZ@?+ZNUIVO7Il57oQo#n*%F(jPNX#)0u5`APr%7iiIoTqUCqu!mey0mpW7Nt-_lPJ=ljPLHMdw}PlRpTWHCaOH#vd_>{XrY@3a zkSGI_V+M-G%|jj(g9cDxC)lk~9owO2EUGLsj8(`Bko+H1bvov8M#hP&(4jE)KQH;? z9k}0B#~}riDazQ|4eJ%u6TDl>Ct|NORckP703{=5J9@?|nsm=*;DRkCrAFfi-Ha|Y z1z-G~-%>1z#>sBoxirn|uNRSllI_G4*9<4YwdS;$Gzpp|?0Wz9FvLZ1ZIZ`LnGCwK z_s>0*2VaG$(jJBKC6qEsX|Uqv33IzoX6sG%8v*+Vw_#W7WOBn6d~2Sv1L0*KZS>wK ztlE?^oVLxDrDj1NAS+-3*Nqx^BGTi<`GlBJ)liX@Jr<;c&hkNE5{^|X26MBEJ9DvZ zky)QQTe`6hXO$!l7@wZ$%1=$Zdt!P+9XA$+=zT#q>5_$IG4;&rb;NQSf7my28#n}|7|sOCx@8aDGIU~3UO_+Z7qjBl}acU9nua!w{NrFP7(3NP11+crO#i#Mv~ zF&qP-eSPY-=f&%q+K^Y}!e}-yY{rsUA}m%clvf1&WC?M(M{h+bdta!_M1*i{jZ``1 zufudTn@cD4DP~z|?eCOWGEfP(R0cz4WNswL$+si*OfmRE+v}z}Jz~0buqHNT)7W`4 z%tJU#b0!4bcbeOp7}~yRYYs@!VHeK#b^2?kb`yY?n5iSb!5wY|GC(`@+xlzkJMP1J zrLh2r5y(Doo;jM_(pCp%-gQ~>dD&5f305-SWQ@SR8nNu?tT!Wj-czxYjl?N9&(LBP zk}dnWwO8K0H(1)du&^*y$$E(1*v?&9vK6i7RgBx0DQo_PRZ8%_iti{Y#kXg{oWai_ zq`>nU4?k#Ew)oP702KqJ(9`m@LQ{y@oy!XPC;jLG%ZvN%j8udSbOI09QQbPP$OL=EYCh<@K~2sW)^L(xD{`1 z&~;b7T}w6p*6FE7z$1kUSsuJsgYi@iRoX}Em*?n)22$+vp&27C`%#J{`rb%&SVucK zB|8dv$!tK+f7*8zIi|8#o5ddDzCi(^Dykz=7uxg8O8?e^J=X-!S<;OmmkPGNl)6K% zJCH88^rh7FuB2g!!LmLm_#V+^%csZj#5Cd|Ok2;w1k>9<(;i{1^IoLOk*Y&+u1y23gpRC) z3I{y4j>TPl!706uwFWcgMqsu?p*EVBdOcG!iKw9!D~Who?}B@yV;1~aV8>eAdt>2A z{tg36*7afsHtK|byc&Y8py|*7k=z!X&EG*47^+RZr-JvR^iB?8xur8s{+%Xvvz6w~KQ=v^g72&u_ z=>^KpiApr@V{t!~hfRZT)^IAfbm9OALe-t-zivLtj0{E~etD$q=6>4W1Ir*9S%`~v zC)+w)_RoIKx@$6iA}51)u?_#%&uL1XJrq{Ts4o~BSnzAgr!N>DfGgekJO1kJd21+; zoN7}#g}3Dl8x=yx(7lfFvikJWOTrxZC1IY(WZM)(*^-{29SOcLy@H(fcY-wpoRy;? zLP>ct3U!c%SI5pVNn07E>d(K8uX{90m*;EG$Y6tk)4OB4fBzmeDC$eInj~U08a7N+ zX!pUIvzp|E-mM*30Z#|-Q}v(MBDbCkSN~xg|8=+a>FUy|_0(kSh|FQ=IZyHBVj>ER z0ow56RN!QymQ;V>iPNDIB_ylhs8F%y9q(N=U$?if@yFZ2#*n$ql?!12@8Q!LOi!3T zv~axMH)eL`@wEML;8#!n1NNr}o>T8TW-k1L06~Uyd;=g~4^B}W!8WGuE-pvnd zt=ejK_9mI?Hg!4SH+_aF>dyl}N>7(G<0CU>@M4Fkvf+0H&Wg}m%p{>EqT!><@yoJcxFDiE};@*%uW<&rgHmi zU0-Z90S^Y8Mw*ukgcvxq1Bvx^za~ij?VPaHv-4R2yx*%kcg?m{;k;@XR^MyE@7X)9 z+XO-SMxc9}Nbvn!l|D0hNkQeXDBmMlurxr0DT4FtA}Ho*xWxJcne_DOY?y(&$BC6S zehRiJn^gUiC&=O7AHy@k1In-?I@jRR>*EQAD?!=C!RS49ZbB%9f|HzsR!6bIPZkcsODuOwaDKTrmdz85AFWs&zGmcAi}7DzBqxv=<`ttCc9OeZeC zr`wwPvqBLE=dx4u^CkhYF(T_?v$^-7c;~q&2S?**$b)oY@a&K|ZJ`KfUONpGR=g_6 z;J8gmWtSjgLWvyBt|Knl2AOj*h$d<(`LOu_~Gxv>!V&PaUb_1NsSU zsME^@UAJV6TN}%VFFHU$fw=H~@rIJ)SJ06Qym|r?`QxzcEXM70;10yHd5_D1*9OT` zPsh7#lp@c~p=!K(+Ftaqi6uefVw(DrgTmw!@_}$@6zpM@sVf`z?c3ZY$6{^UA^s5e zqFbgZzXSe#iDXDrTMKB26M|XkUMRi_@Nl;viyLSQIJ z6Ej28jM>l+2cHoB@FoYM{L#w82{0`3#j5~2T_0iI6_X+W6r=7PaK_fG{Wic`}v~N&THX zNx1JLUgRe2t&M}dm8^2u4W%)WZ#LL1yN*8uREvqDFuzu;5-dNMx&~OOaIiPqayDjh z9`XN%F3?RlfrYL|nl~YNJ4swqKTt^s2x#*HfIn(VN18T1^TQvPB65t(l74P5yYxAt~I-}QB++ztsRTd24Lfol2zcy24xQh>{IbvY@HxkGkMJ)XB z4d4$a?FEaWgI9JSis&6)wpDWr#d34KQcnfFIA%zxbWrXyNnmcWD&_5`0|uXU8 z-^*>AeX-Ap-o9JY;$#kUj|h7LpEy@ewAJ7N6HX0$Hv5kVJe%T;y}USvovucG;)Rx} zd()))Ph7V_ht$k>%@K9Xh%P-*yso>WKmb2d2Dh3vIU6|F4`Lx=JLlEVz1z*iE7#PQ zrWD{MLpBU;Q99+XjDk~5U?Vo&`Z;yF46DX>cB4IKX z*q}r^zA4ce2Z0_)s2q}`DKYIhr;P9MFS?;I0uhi`IC6f+Z(coap{q0WrQd2gfL~pM zqa-o-ZWHBODa`k$*Jm1&TX8`SMLNABcw6m~brP3d0m1RBC&Ub&Fu_QYR0v_O-BvA+ z(^;el_;&9L(5Jei=m!5dEt>qudL2xhVqi?Ca6y*U8%`HH$a+gd)UGFQ)f0gSP^b8z zzK)|eMXZ#p;vfSt+(*`2d+CCtF=PO$yG~iqm#u1zh0y4=%S}hTZ(xJ<`Y719Vh4bW|y{lB;c!x6ttJt@gvX z3x_*T`U5zy!u1o<-zm(itH?G7y~od4UuK$i71zVmN|{PGAw~GtG-IZ)K#KOc_5~D| zXJmeoeDmNKY)`(G7&&Us~x9dig#5(Yvvc=ql213|$ZIs0KHs$21BiIVedlh-Y`aMjfWe&z0lAxzs0 zuLl;`z))ivPW5ys!A{2luwx^FQlIe?=Ndut3AWhJ2Fc27FJjsY_w}72w+}O!rfvgf zwLONL1%ezA#l4%A>Zjo#96^eeINxyP?qECHHq3$jw-l^G4sv61dVGP%IwHt|iDKJ| zQ_9`KiqydS13Oj0Ic`MG)S~sb8Y8EL5KGSl1h_mUb1wOML2(y!KrbIr^AQQ%PAm{p z!_VqpMM0c97BTZZAnQKAw-nhMJ;&+MEK$`kG(*0tQhAVz2X@QI8(j-Wa)5P}(E^lx zxLPT7`R~jJ^9yqSYu8UPA{TBSw;Df~Krm88I2bO}UfXmEeOY%9<5LPJOwQcOS%x<= z9mMb-=&t3sX!fgTfG!p}M#=-{qaAK>P#b9>8vZB4mSsLpTWpp>$fuwENeAbyPU6+^ za!(#*qBzg)JyRiBf|w%upn3l90JKwBfuv@L0(m7whNSRl0ocY1k?jm}%U=dCy;6CJ zv=F(UGQ$H#APHs_AltdI!D(-J-0rx4$Ea>b1{R!AIRYA>fvIQgTlsLon_Eh`FtjW( ztN?J1e3;!%5qmUKJT4mnhd?GM3aO;7j*Z6CGwlQCJFf1Ea`h8ImuWmc-Wn#XQs=I{ z-tZ!#O*KvLoqGv09LtLf*U?H7``Dc8EbWa9m&@oEP)!=cAx3x52v?l1%L~n!hiYR? z1=dXVXBPcn0Kegx`!AI`$10q_xP)`8#qE)JtCdka9>!Ynk4?j?UMF-YG9IQ+@wO_? zH#5x?4{HZ;A>#Giy(k{anV(4t`}qbx--r64`R0E*IAD*!?vV|Y2jNo$4OHO}uz{zW zlj>ZIpMg@Ba#HqbTWn$y@WlO|cP#dP{CRi9nM*TQ1`O0~P#0dtn$T{->{9XK!+uPie{T1sryR34t1)v|k#!Rfy*UODK@_Gpw1=|(avMjXUc z2yV9eK+((gSH$q3D{_sxfJ5Wp#91(SatPE)A{bJIfEm~!I*``$+pL_Y zy&>CW?!nuJUN5LW={H8^GOecv&J#BM7|OrJ=4z*HW2#fVj@TTophvLb^St-55-Qjw z#JJ~zrNQAWe`gIO{c617hwa`jx(ErV{K=e~+ALYtR$#$}pLs-0qkRtd8?v=Nipc}S z5jaD2#4ZT7BiK?v`_00!EkMMUOB^OcE)1R!>#B;I5QIZl`b&8HG(>Z0MIB~6Iv~R1 zpk2nSc$j+|w990bzGAD~fJcm?)-$pxeX9`SxU-!7s-Ix@-oJgRrw^`28guz$JTs?A za`9ta7d5H84>UbyKYKeC@Qt8rW~w4v7s$4K~PG)%a|g?lV`GU zJ{{tMWCmZ0Dl=P*OQ830AjCyr>tTtfs)AI|8J2526Jf|IZyq6A&a(1Hs0R9dGD}66 z#l6Ry9f1Uj8pbAKB6Ckk;&RNEXcT$)jvmWKbExvg!i7e~dlUwH(F{;3;t4#_0*E`v zYdkdcmmWLLG&u;zvUa?wN*v;SiH!QBi3ZeNzx~RDXk>y;~B@>=l|# zFGo`J-T555XL^o)|3xokqGk+ZJB@@fenkS^u}rG&&cttD&Y4qBW8{V+f)i8=^bKxA-Hnnsu7R~&+ivt+{oF* zmw`P$&8bzWnl?rwakkjtNn`LA=4O`w-hF`ubm>yr9|JdV=_ef)Y0v12|Gv04RePW} z-$Jpy<<2;EWn|rK&`iAxs6UkVV~`8?8e?B3MY}GES?7tbuI3U(^U94gG-3|pYJ`5!pJ8QSB!#nM zB0f3ZGfd;vqP>Z^;8N|sg7}R8345^p3kKKOMSCD}kLZxoRmL@Qh+5IkB`s}L*SC-v z;keI~3sH{f2m)NMldyG54;Ye4%Z&TUYz{$xOvLaSHskv8wt=MhcemWI)p1UbH3+Jx zg3)mX2m11zcKhp=J80<67H{;SD~q@PL>t^Md+@jOD~ETGLolvHnVM+Z_$4m3BP&HXM6({p8N0Qz}W{of~;^TQf63{$x&ID-zK z86xpuS^@b8c}k|XuQLbTh+(OzW^Gf^a$*iT>daFb%_)-;`*Kq$9@Hzh;jgZcW9t;v z{&b?(YxsMs4r#xU9CU~amzhLb3-Z#*2yy%b! zaw@-Q^OYa;nkw6;i{3q@^o-mO*}t&rGk#S^D>^HGDrPcZ2WtgIoKcObzaUd15b$Vr z1z5IwHQZIX8oO;Gf%-}J4S_&>CSX(?TnCXQe8;g_Lm9<`9I8&A8YXfjTEZJ2wiA?Z z3sIeYP-&M9X(E~Ib!CAaJQ6HWq$vIGvUn{N1m?dd1Fn=ieJC1WD|SO79(Xp$O9AKN ziZlY;N5()~R#&ABA+)`*`bbjXxzNl*zDZ~PR=XS<_`K3tBElH6j4sT(oTBiIOaIx> zUjDkGzO*!Ci}a-?TW-cKfV1P{EHjgngX+UX#!5dQm6oPLwBa3kb`-1rVa{7CjkfJ*!m7G5Ld+q3PayBtOZQdbt zcJ0XN>DRrRvaffag$n!CP^M+Fk9TCsGq!U)+fjbo%ijG(%%8JK9~gdL$2C<7bM5j* z{0o(EHS{ME*ReF2XeBaRyP9Rwg~TPZ{B0oaL3d}52-Qdb94GuukzOsXYgYg79!Nv;i^P+9W1Ni3HjY_mZw*!G># z^Tx%hWPPQ6;cyWU=wqcVN(`ZYX}Z zf~AKHu~TNuG+|NMsSjA$$Q*aP6CTe@ZoOZr^XcVTBPq@xVpN`xY*8jWbpMS$@cGgn zxCHn_PCd_XVwpIDVS|YEu2V7=U3Ykc-?A{}Q{1`lm<$VR*J1`B!I}Lq&c&^bana*k zxR6k_YULn%dA8tfw|$RSPEgWkK@6+KIpFv>8H;rcpf-$cxPDMhWu9 zEO^uAL2D7kGQ*n2&d+z5^$Zj#AA_n0bc?|%uNUIJ>vr!WC~YXGM>Q<~(gYwI|3q12 zRM#Vsna{34{3t1DDKspboLsmK2{#)vwekudX8qaYO`enbk*r&E=m-a0zay!{mHCm~ zD*+v#>RQLk?)c?)Ty{#-4MD*i?{v^0Wza{MWvV^DjkQWF?d!^1LQ}?2s^Ht^r?F?u z#LP7kx9cO`lJfVu2yzAh`7UO-D0O9Vf5#>O;UeeOUK@ohNye0!Og8<2WKESX-4F%U zd_To9%sZv>!F9uSKuyS;73iLBsTBo2y>oex>6*EsT!qfQ%lB2}(Y8hR190Fdh5=PE zz;(?!$lT_%>#wlp+^H~jUf6zpp4$BdS%-{#0~~Zvg*`=& zAhEclRxVQYC%H|=fF9qoRV}rPe&?rZ2wxjo_nGv3@$?36vT2JwLXfQDqMwkUD(*aD%`1lT^m&;^lx=N!P#W<(#R{f4sRIym$a4bXi4$zEO)ja zf6F-P&*s4_I7|V&;SJ$swGi8WsoO-f>mF7teFU4qM#)gPR>V5R*>H|JWvo13du6q_ z{{6RkHK_u#*&{%9QO2*u{u zc-`}s>+-Itu6`4=#9VtTu$kFbP?d}#YfgHH{qz-e0-gXsF3aHY8}`-5)? zuAQ~H^V9jw(^ea@guH-YU?r{9y~(O7Jw7WB0;-Bw$Ay4o+m zMH2u!)ech8$-p6NtrSiK@)?-*=x#4M01q=oD74jYj54EySdIC+Vhe)IkT6JEu zl-&alF*|`6hfheV9G0kjdM5Xjj-a`#XrMT-e6K5pmo@ZxZZat{39zW^bbT5a{vm!v zxJuoNv}A_FF`~nfN+~Vx6wbFkLWpU60tH;^(JC5!`PK(AnlP<$AWf4xz(*S}1j*em zEgOJ2kky59lr8G{-EUn;4VDx|r;C}*|HB&~L;FCvGf9aF>zG;Gz4O{l;}&v{gOJ>z)WUyYc09*$9ly8J>lV(**f28@zIBlvSc|=Gym5 zO&u%SKkUoqMqyx}W_#>xfrKE+-PPS8o=(5f{^c5RJtGTa44LL|&@s;+jZNDN0k*#^ zmTN_47Rs5NIKbMxk6q&+$%39|S%D4jwrJk~#}SFZhXeeHt`6|xtLYK=sz-K@hITiI z+pbjNZ7a}$Ulos=PwXs5_d8}yq`pbc=|1k(Mw03%mYqHj>Aa{Kpj1ahLtsKgh?94P ztvbuoXnrEqm30BAmGWT0#t7FTmHEqg8|HLm8!Q1PFpoLN|CqUKnJ&qDJ zOlhVt)_8V0qUh}K&}l`zrD(1F2eZkWTD~FW2+x3$U3Eq2Fa-js8#GE#O@s@|CUCDZ zk4sX98nB+m$wNWRPfWM8P6X5@#>5W5=8<~BXW&Q4LIkly!b8msLbZThYiw`kampB$ zer%#FOnBb_O>rw-4BFx_AO16oIirN=5)PCHceoVA>sTn*3l+a zup#>%f?0iJ0qr~zhVx;)DgudXlfKvayp?N$_4i_ncfyBx;mV#dfPBnVuS&0C!e?=4 z+_vD-d6&i=L8Jm!uL}9P=TEtt0EofbkX|my=LOM&#hC2H4OMmInPj=YBFsk!p{;d}_2aCfHV-)lI zTeOEbelSMx$LqmY6HPT$rirCvuc5TInw!Ul&_fw9S@${V$slfV5&t4~%BH%{bDS9q z>abTU!!AA@h8pHT>QKq6P^aS|#6Sj_EcU8&$Xupadzc7mY&h#MYBn*5O<+>dMasbn z;<>G>TJr1>Xb_ChC#pkC0P$$dei>Op=ZF8y9F_zjSEe<;gEosgg^n~pZA31Nv7DP5XCoKh16N*Q=# zkfPeT_vfvg==+m?69b=(!^H?P-*$Va5SbR5(82+JC-JET%V1Jr+M+BeE)0(TdjS8P z2ubz|*#60tM_GV=PE+p48IANXBMo#dgd(wYU*(C=GkUagjOYBge7=!?yKuw!Y_H{g zlQ-Ubj0|&!K5n}l?1)7nspX@nRPHC#iUAe1>+%r!!gaMYENPqzox%kDao>3?gD|E3 zb5ZyOZ5-Xjo{mk)!z+u0@E(w$a9uKn<1qdJdLvkIP=b`-`IhZjh$|meM}7!8M?D@C z+kfg0YM_)@7Rv*w_EO}Tz35#i*xeoU?W7Sljqu+aY4cxZw-2>`l_yF)wBpt=fv7vq z%LanM4~RbML;9hPVGEXAoBcMjrxq0%<03nd$L#DHX*EfrTf;28Y|)s+s`zDN-9%Xd zDD;szvXKxdMwVAc4pY$6YL53_8Bvzc<|s)Hj`Y8(!vB0f@iVRDJgiXp?;ba({}m>I)Ak;u!eH9UJ`aipOZb*EI(shAUk7hkdxiSF4Qeh z2J>O930fF$b#Zo-ZPV7aR(-#&7p?H*XQ7GPQ0n8Xn$XG5XhOizyHAh=(D*7&6`ivY8r* zi8z>AcmuI(D?%6~qmtVz?_cARe9bj$tit1ie;y6%L(NGfK~EZ9q)}fv{!G7%R-Oxr zy!tS(?ghw-x`T3ywum@L`a8g9AjPc(!LPv+t5iZ(p*+bXu|e_LcM5QGd*4OQAA$2CpC)D-EFMVSWwIL7^cT#S5$LhJc*Ocw%!5>BP zO1YAAP5m<|5xIWuvUl$(MQheZR-alB&ij3738p<=_&oBAN|A#k^q}X>LDAL_ zLUE$FuISZa;+Ln8=m$4|xRm6i)(g#Vqg^DE><_Q08us&|qP}VXTY45fLH5NcspA~R z&9lg}@MV6&FK6$_wVUCGW*ux?M(l~!jWuLQPV(VrV6bF4I-}lJg#`0T^^uIRD^>WC z-Ur3g`jSDv`im3N#?hH!k@O1y5c#RAZ-V)>~@vx$9k0t1YoLDYg!pM;G z0iVE&m}0bs@}J29r3yGqa28gU{~9f5q0R#{1_eD%iOL6S20E#JQAC)Ak9z!mBytD~ z>&aSfbgGpv>-|fQuW-Wr-0uyXo|y5>B4p(RK76|gDJJFF+H(jXpko+eRj$aZ`F4Mj z431!kkf&Mn-4*??N1j8cto~&RifKtNT<#-D3JN=-C2ec-yHBcp0!OD}gUd?x`}nu) z;g04?4#Qi?AHce^13BKtkJX{&_mLz8a@CY?Ci86$OMwo#A`wN<@C2;&^>uxG-vu*X z2{rkA1=y;z7j!IAkFlG4*p*!R2PZMu_-uP+f2$WOjPB&`hD+Jwe_|D=hqc-;`vgZ- z%(wf1th4fr&%P_==a>QDWMWt46OLz? z0{dFXtJjbq)RKkFGXpjZr&LLEJDVLt7<`!LBt`2)M!52TVBcoiMtAj?lXGH>kbEu= zY6i?q5J3Bg_o3L|N$YMubjEdy4P8uBdnqD%wOuG+s_h9HJb#v*gg?HKOqtP%6A5Ka zO2{jV6e-BcKv-TljmH26-_0Tm*hd&Ipt`@f2oh z#ih{sL0Qf0(%@(3i<3v+21jf{SzrhvHwJcJ-cs5!@21Q5I4G3Wk@YEh|Ah_JXib>x zL!5?A!#hFdV^E<%iDOa@BE>6q|J088AL+uxE^OW>-&ii&;dXr6sM+*#W6U)XzbOfL zzyi>v;tJ1pY)2!+?sVSpj`H20VC3lE=hHN>SBImKvL99{Y5G`)tDnXK>c=Q)eW|RS z0+fPfb#c5NJlFRXwUP_!9`e_Su!aoD?~S+!&6$7doe2-dY0!qfiJXjRa|tR>b;eD1 z8GG6D+$urlM!B-W2V+-n5fW?Bp;E&9BM~4TlT_6!#idvVgB|Oai^XP3uOGlfLyVCM zvwR}H!jnRxfYOJNZO1c;iGH%+5s%e3hJBey3ws9XBcn6Lmb^6$cz3NDI_M2n>+(i5 zh&d3KJZ1*A=gPQdY4)Nx&ED{G7FT^}q>KnPn4YAO&``@tLhHj>v-Hvas?m+bvjIHv z;heIU$bL2ro_Q6dgoR9rDg0{}JpK5G5?%T4@W?bAoFRF=azh!3# zjSStgJ%K}6x0o3!~9YQ1@t|9>)pS%Z)q}OgSXNs@Ln(|9k73Se~%Z0rEjl) zV%0QqApcB)hx*sMOv~)-MQodPs;!W}=vuwFT`gN*=_+{?w<>4uH^gs}`ZN{XA6he0 zDaJi3cKJs&G)v(vlFkWhdI|`z-nTi}z`%?OPPJ}UlFv0X6pip10cX3<9_zr&uSE)=msJ76OirKHT$v!ltJIS)#5 z4(t0H0`h!O;R&xFw%wGp5N;Mx0Xs7;$qBO+2zbNvV%PMq9A$Ui;8bQ#mjAZ?Ay%0=+5g?WVEF$isRq+vG%YC=U}0eYjQ^sj znpJ~I|0Al_R)fidvbB6xgKZ+DC{2Osr*L(GG5iCS{{JL!{SUkKKN7h9hu!)g3Ecm~ zZv9VC?*GlYW#;}b3E#lD|33{RU0{L#qv4_lOe&?O8cYtHg^9H#pciZ!0hIec@*@9N z4iFibS^ghs_g_2~rvFL6zj!Rn|2qLJ%q;&oG9EY!Gi%GgL&N-s8v7p%5E3`X|HA;W zaHPb6Ls9?Z09pTMW#>n=0rL)8!PIppQ3z^p3|UEOG+f+6O0 zw4TboOukgO%Q^^H;@#F>7O(mB=1Dv=4`xx)9Bv>jc~m`hLfCkQ6e%@Pbiea#_>6Y2 zp)>|2oOYzfoHv@pQ2z66oa&fS-5ka?+%TH;ix$v(-bsfr{z6LIho40j%pXsjduhy4 zq-E*~Ql%F%K=@(WXr0> z430bGeQ8Ks(D<&+9sK}Oo)Czmn#fAJWTi9~$1)BIBiNKndiSFeL4s;>XmmlVM0XjM zR|^=W)jtlnUt|-qI;x`JFc+c_9jCd0U{pKQBmaJq^qd|~u>4BwjH?#cmhW@Bm=N0e zoBM=>QH1Z$xk)_ksC+Ul|6%bcfkT|Yx9mAlJ0vHGRG~ROvSuWWYjQ74U6xhQ2@$r# zfjben#Q5HnNF@z%`er}+J_!MYx$t6#xjG=s*D!3%^BPn~j@cP9ikU)EzAv{P{mQh) z38gSxtpj>W^(k8Xi2T$9jH10){4l;uvNZ3MN=;>GE)%g5XN8~+y0Qggt%XZHeiIZT zk?w7tp=lX{UV=#c*_b6g#JXuyD1tnik1~eMn}9{qX$_?{iITcSWT0sp9m96YiynAs z?LDX@re>Bv9X1_!X$hI4Ab99f`ZkjVf^+8$5Ak^a&KB#jO@D_DuXX?17aHu;pVUgsGT=2=VrGP0u6xGvbWO5 zk*5ahc9~hR|HBT#v2Q}1X%MNUyayL~Bw@w8%eO$c<2aWygFPXx{_3D5$Ba>b#;ZXB zH*K}zd88n1b5;N!uCL~3!<>BD>(lS_71I#)0eWV)6{VLrPnPx@PZ{#}gU<^n z4LEVW9nD9h2g~A^_7Gs!d*xEtxj>sWT^@G?g6hhfM9x8u-zon$KxH2d z^g5IZgq2;Lq4qIw8$yJNtmS=QUGtq&7BMe^1V;{}*8JW84tGZE>Q8ths+Oq1?;6)4>XfrvEH+)#5~Vv&xty0CGw zR=Ir$3qLR+SV@_!R0LRs`r-7VH86huYbES@PQr+4t@`;OBjn6h=hQK3d`KZ&`b+sCq zaJt)`ww!Q1X|%LHX?*w*%}9M5WPoCn;wuX;Vn7f#%;LbiY9;0njwNBZ&oeTmH?mdD z)-U4fukx|lWTKV|IQZRmfgU0ByG9rF$@BR#aQt{a6M z8>+xQ**%1G!c2~;+Q7&pp+Uonq7BRPp3t{2zLX@(Ci~LxA zW+(QGr$=WJKS=7GuZ46wG*b83+JT zPrBA4=_|rR!2B_MRS(Ec#oZlG@__WsWhHkAn)d)To0G%KRqT?0+?B088)@>uLZ8}R z&Cnn7$5=C#q2+P)VNqd@keXRo`r7gw809W}9~&j^^!o*}$InVm-YgFON5^h7%L10z zc3?$#Ll^EnldX2O?vl#)3p>*K24Wb78ansrX6aZD-mOWgx3n`OECI z;D!9Rx_7kWmWQiSK>@<3?Iy-eZdXdGYC02UOI%rf{~`SWv>Fp>_YpKFXj$E16%E5N z%{sAP1hQ?sSU1VF5M2-y7vJ)5d~arl0)Bk|%ai)^8fkbnDPru{jP2d(5)Lon%9YL6 z|2SIaGCVPog}Y9(zY?xpw%(;Xcf+91U;OB@NuSQRrF&YQy{I~w z2UP7kng`{4GodX$q7`=HMGQFwi>NjgC3y0g+)b9Z-j@(R>EDNe|agy^3A69K0i?>bZJrr9~rg8853T{b>?dJG7)?Dz!0a}OKs3QO>k-+JCno^ZI#-6n?Y=)j zUyAZxS#5F{#|^w&>|LRA=3xGZz$YJxv$?M;5_S+m9iH!pR7;pkup!q>i$oQLa@E>B znFTx%`?xTwn*y}*Y*U;p7_UjIeLj@9s+fFX_!0TDAI#JEVS%-(LGTY3KE2vZ5_dM; zDIpN(Wof_pNb3h;N9D z_I|;rqOoG|59iwo7ndRn!0}e4i;F=*qhz+zM0EYV>VTCbiKQE`fkIOP5p-wPTl>>W!1+fWLz*_)NrkC5Q^5rEU0nYE? z&J)PIRML}`#X%NS`6@W|v$HppRUy4tKsZt>CwHu@BvA1Y;|JjqqULfzUnvP;_Zc2( z`10Fr>1)kx#Q&k`D}&-{nzn((-QC^Y-8HzoYjF3)-EDCT5+rDXySoOr0KwfIK5{?b zTeVfEuj!edK7Y2R=k(S6jGEkXjzax*gF@54kMRZ99(ZbX3_hgMT^o5ycA^^FF1&@< zS|freeeepszSKF}-kfUm5daY2%VH85tM^>9wc1_u$R^4V@h{hHI^uL&xBcI9^MB9S zO-ncHUz?S!UxA>8Z(U1vjhb8f#Qc+yN;gIG{)e0-{FBoQw!%N-Q5<$JHn}%Z(5^c0JB~F|4w@fMH&CcVAWDed%68&0@kzl^EvT5F8ICA5n1Ls1n@7g2k7!Z0j-)Q>hUfPL zB`W$Oc<8S^a<9s+?O?KrU^an5HMM`ZtKp0`Yx;jP;8XYN&^T`No#X5GWIhMeHMt75 zSlD4*@UJVQ`_(R*aQ})+xiQzqv|jy1&{^v#HSbx6OCwOSBW&TwGh1&X`6_O^)@4&p zFyFzF60Ev;($OjrxH)STn`oZEP*$629<1%fNPVd!<&~Cd`}7S1wJ8T^mZ%^jjm