From c9b0de4301b7fb1828d1e0cab59d9b9d782f017a Mon Sep 17 00:00:00 2001 From: Yuichi Motoyama Date: Wed, 27 Dec 2023 10:10:44 +0900 Subject: [PATCH 1/3] fix shrink chi with RSVD --- src/iTPS/core/ctm.cpp | 4 +- test/CMakeLists.txt | 1 + test/data/RSVD.toml | 316 +++++++++++++++++++ test/data/output_RSVD/RSVD.toml | 316 +++++++++++++++++++ test/data/output_RSVD/correlation.dat | 61 ++++ test/data/output_RSVD/correlation_length.dat | 11 + test/data/output_RSVD/density.dat | 8 + test/data/output_RSVD/onesite_obs.dat | 27 ++ test/data/output_RSVD/parameters.dat | 39 +++ test/data/output_RSVD/time.dat | 5 + test/data/output_RSVD/twosite_obs.dat | 54 ++++ 11 files changed, 840 insertions(+), 2 deletions(-) create mode 100644 test/data/RSVD.toml create mode 100644 test/data/output_RSVD/RSVD.toml create mode 100644 test/data/output_RSVD/correlation.dat create mode 100644 test/data/output_RSVD/correlation_length.dat create mode 100644 test/data/output_RSVD/density.dat create mode 100644 test/data/output_RSVD/onesite_obs.dat create mode 100644 test/data/output_RSVD/parameters.dat create mode 100644 test/data/output_RSVD/time.dat create mode 100644 test/data/output_RSVD/twosite_obs.dat diff --git a/src/iTPS/core/ctm.cpp b/src/iTPS/core/ctm.cpp index c5602313..58f249d0 100644 --- a/src/iTPS/core/ctm.cpp +++ b/src/iTPS/core/ctm.cpp @@ -433,8 +433,8 @@ void Calc_projector_updown_blocks( tensor U_c = mptensor::slice(U, 3, 0, cut); tensor VT_c = mptensor::slice(VT, 0, 0, cut); - U_c.multiply_vector(s, 3); - VT_c.multiply_vector(s, 0); + U_c.multiply_vector(s_c, 3); + VT_c.multiply_vector(s_c, 0); PU = tensordot(LB, tensordot(RB, conj(VT_c), Axes(1, 3, 5), Axes(1, 2, 3)), Axes(1, 3, 5), Axes(0, 1, 2)) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e8a564dd..c4d26b6f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -40,6 +40,7 @@ foreach( AntiferroHeisenberg_real AntiferroHeisenberg_complex AntiferroHeisenberg_mf + RSVD J1J2_AFH Honeycomb Honeycomb_skew diff --git a/test/data/RSVD.toml b/test/data/RSVD.toml new file mode 100644 index 00000000..c141467a --- /dev/null +++ b/test/data/RSVD.toml @@ -0,0 +1,316 @@ +[parameter] +[parameter.general] +is_real = false +output = 'output_RSVD' +[parameter.simple_update] +tau = 0.01 +num_step = 100 +[parameter.full_update] +tau = 0.01 +num_step = 1 +[parameter.ctm] +dimension = 5 +use_rsvd = true +projector_corner = false + +[tensor] +L_sub = [2, 2] +skew = 0 +[[tensor.unitcell]] +index = [] +physical_dim = 2 +virtual_dim = [2, 2, 2, 2] +initial_state = [0.0] +noise = 0.01 + +[correlation] +r_max = 3 +operators = [[0,0], [0,1]] + +[observable] +[[observable.onesite]] +name = "Sz" +group = 0 +sites = [] +dim = 2 +elements = """ +0 0 0.5 0.0 +1 1 -0.5 0.0 +""" +[[observable.onesite]] +name = "Sx" +group = 1 +sites = [] +dim = 2 +elements = """ +1 0 0.5 0.0 +0 1 0.5 0.0 +""" +[[observable.onesite]] +name = "Sy" +group = 2 +sites = [] +dim = 2 +elements = """ +1 0 0.0 0.5 +0 1 -0.0 -0.5 +""" + +[[observable.twosite]] +name = "bond_hamiltonian" +group = 0 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +dim = [2, 2] +elements = """ +0 0 0 0 0.25 0.0 +1 0 1 0 -0.25 0.0 +0 1 1 0 0.5 0.0 +1 0 0 1 0.5 0.0 +0 1 0 1 -0.25 0.0 +1 1 1 1 0.25 0.0 +""" +[[observable.twosite]] +name = "SzSz" +group = 1 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +ops = [0, 0] +[[observable.twosite]] +name = "SxSx" +group = 2 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +ops = [1, 1] +[[observable.twosite]] +name = "SySy" +group = 3 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +ops = [2, 2] + +[evolution] +[[evolution.simple]] +source_site = 0 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 1 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 2 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 3 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 0 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 1 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 2 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 3 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 0 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 1 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 2 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 3 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 0 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 1 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 2 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 3 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" diff --git a/test/data/output_RSVD/RSVD.toml b/test/data/output_RSVD/RSVD.toml new file mode 100644 index 00000000..c141467a --- /dev/null +++ b/test/data/output_RSVD/RSVD.toml @@ -0,0 +1,316 @@ +[parameter] +[parameter.general] +is_real = false +output = 'output_RSVD' +[parameter.simple_update] +tau = 0.01 +num_step = 100 +[parameter.full_update] +tau = 0.01 +num_step = 1 +[parameter.ctm] +dimension = 5 +use_rsvd = true +projector_corner = false + +[tensor] +L_sub = [2, 2] +skew = 0 +[[tensor.unitcell]] +index = [] +physical_dim = 2 +virtual_dim = [2, 2, 2, 2] +initial_state = [0.0] +noise = 0.01 + +[correlation] +r_max = 3 +operators = [[0,0], [0,1]] + +[observable] +[[observable.onesite]] +name = "Sz" +group = 0 +sites = [] +dim = 2 +elements = """ +0 0 0.5 0.0 +1 1 -0.5 0.0 +""" +[[observable.onesite]] +name = "Sx" +group = 1 +sites = [] +dim = 2 +elements = """ +1 0 0.5 0.0 +0 1 0.5 0.0 +""" +[[observable.onesite]] +name = "Sy" +group = 2 +sites = [] +dim = 2 +elements = """ +1 0 0.0 0.5 +0 1 -0.0 -0.5 +""" + +[[observable.twosite]] +name = "bond_hamiltonian" +group = 0 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +dim = [2, 2] +elements = """ +0 0 0 0 0.25 0.0 +1 0 1 0 -0.25 0.0 +0 1 1 0 0.5 0.0 +1 0 0 1 0.5 0.0 +0 1 0 1 -0.25 0.0 +1 1 1 1 0.25 0.0 +""" +[[observable.twosite]] +name = "SzSz" +group = 1 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +ops = [0, 0] +[[observable.twosite]] +name = "SxSx" +group = 2 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +ops = [1, 1] +[[observable.twosite]] +name = "SySy" +group = 3 +bonds = """ +0 1 0 +1 1 0 +2 1 0 +3 1 0 +0 0 1 +1 0 1 +2 0 1 +3 0 1 +""" +ops = [2, 2] + +[evolution] +[[evolution.simple]] +source_site = 0 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 1 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 2 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 3 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 0 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 1 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 2 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.simple]] +source_site = 3 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 0 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 1 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 2 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 3 +source_leg = 2 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 0 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 1 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 2 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" +[[evolution.full]] +source_site = 3 +source_leg = 1 +dimensions = [2, 2, 2, 2] +elements = """ +0 0 0 0 0.9975031223974601 0.0 +1 0 1 0 1.0025156589209967 0.0 +0 1 1 0 -0.005012536523536871 0.0 +1 0 0 1 -0.005012536523536871 0.0 +0 1 0 1 1.0025156589209967 0.0 +1 1 1 1 0.9975031223974601 0.0 +""" diff --git a/test/data/output_RSVD/correlation.dat b/test/data/output_RSVD/correlation.dat new file mode 100644 index 00000000..a08128c5 --- /dev/null +++ b/test/data/output_RSVD/correlation.dat @@ -0,0 +1,61 @@ +# The meaning of each column is the following: +# $1: left_op +# $2: left_site +# $3: right_op +# $4: right_dx +# $5: right_dy +# $6: real +# $7: imag +# The names of operators are the following: +# 0: Sz +# 1: Sx +# 2: Sy + +0 0 0 1 0 -7.32392667575661460e-02 2.34151715175363834e-16 +0 0 1 1 0 -1.30337976488469915e-02 -4.12903877156122571e-17 +0 0 0 2 0 1.72554010890249923e-02 7.87672776725466269e-18 +0 0 1 2 0 8.01440081852875484e-03 2.52420400446688458e-17 +0 0 0 3 0 -3.34613032951389328e-03 1.99731312809506843e-16 +0 0 1 3 0 -1.12964449459852945e-02 -5.38639930659119984e-17 +0 0 0 0 1 -5.72781167132934838e-02 -8.53257967299699964e-17 +0 0 1 0 1 -1.65096228197929469e-02 3.34917618366929945e-17 +0 0 0 0 2 1.06230561128399098e-02 -1.54988950593509495e-17 +0 0 1 0 2 7.96569650566540666e-03 -4.28092186541338309e-17 +0 0 0 0 3 -6.17029511091326545e-04 -7.83126807557056929e-18 +0 0 1 0 3 -1.28288045212802838e-02 5.83332509377625523e-17 +0 1 0 1 0 -7.40191966989294514e-02 3.57533802733460507e-17 +0 1 1 1 0 2.13652377618094979e-03 7.58164307486034170e-17 +0 1 0 2 0 1.30302974233575293e-02 -8.28353759233207556e-17 +0 1 1 2 0 4.30765711219797520e-03 -3.38878764283302300e-17 +0 1 0 3 0 -3.37668707522936718e-03 -9.79018140170540698e-18 +0 1 1 3 0 -3.07012810217392046e-03 -9.16071044899100547e-18 +0 1 0 0 1 -6.85246833238848940e-02 1.49985100477003819e-16 +0 1 1 0 1 -8.44530264089174941e-03 6.07941373523806977e-16 +0 1 0 0 2 1.14669766786817499e-02 -2.23970256218983046e-16 +0 1 1 0 2 4.37217364003373264e-03 -2.30359937292517149e-15 +0 1 0 0 3 -1.66281490097187879e-03 6.06197940363295390e-17 +0 1 1 0 3 -4.81693832191851419e-03 2.32452521958320100e-15 +0 2 0 1 0 -7.67421777014239276e-02 -4.78430103714562640e-16 +0 2 1 1 0 6.10763719888219366e-03 -1.35741432862867843e-15 +0 2 0 2 0 1.60143412905684734e-02 -8.72950250843715625e-18 +0 2 1 2 0 -9.84354555446051438e-03 7.69562518507127665e-17 +0 2 0 3 0 -3.69821059323026044e-03 -4.45010806640855690e-16 +0 2 1 3 0 9.99162752449843199e-03 -2.18579124585843271e-16 +0 2 0 0 1 -5.77942520236587598e-02 2.33985288847030765e-17 +0 2 1 0 1 8.76995080534252042e-03 -8.41031130877468739e-18 +0 2 0 0 2 1.01476568145890574e-02 1.67939499066944365e-17 +0 2 1 0 2 -1.08329302530083930e-02 -2.46844629558017654e-17 +0 2 0 0 3 -6.30900275759428307e-04 -2.30568528017434049e-18 +0 2 1 0 3 6.94578257405916496e-03 8.08641239349770075e-18 +0 3 0 1 0 -7.76019781613517812e-02 5.78842559019323707e-17 +0 3 1 1 0 6.21580953859463686e-03 6.31806643935937738e-17 +0 3 0 2 0 1.48172042935909506e-02 3.22224749790128655e-16 +0 3 1 2 0 -6.55289513177373557e-03 2.44312214470257238e-16 +0 3 0 3 0 -3.73048905812711383e-03 1.48929078125834329e-18 +0 3 1 3 0 9.28188667045837593e-03 2.56796339712087483e-17 +0 3 0 0 1 -6.91966672009472900e-02 3.58936263595607697e-16 +0 3 1 0 1 1.03099603613698888e-02 4.99865312227967816e-15 +0 3 0 0 2 1.23288372195748432e-02 7.02256990475590184e-16 +0 3 1 0 2 -6.90499943402277626e-03 -4.91274724391301249e-15 +0 3 0 0 3 -1.68174419670151401e-03 4.78289342237608812e-17 +0 3 1 0 3 8.47058761681369551e-03 5.27119866204667239e-15 diff --git a/test/data/output_RSVD/correlation_length.dat b/test/data/output_RSVD/correlation_length.dat new file mode 100644 index 00000000..a04e694d --- /dev/null +++ b/test/data/output_RSVD/correlation_length.dat @@ -0,0 +1,11 @@ +# The meaning of each column is the following: +# $1: direction 0: +x, 1: +y +# $2: y (dir=0) or x (dir=1) coorinates +# $3: correlation length xi = 1/e_1 +# $4-: eigenvalues e_i = -log|t_i/t_0| +# where i > 0 and t_i is i-th largest eigenvalue of T + +0 0 6.88695039985187107e-01 1.45202149273720438e+00 1.57319977106406683e+00 1.74778134044166000e+00 +0 1 6.88697943894192699e-01 1.45201537025879923e+00 1.57318870616615114e+00 1.74555305749211609e+00 +1 0 6.28667030345474553e-01 1.59066716040519096e+00 1.72559130373946146e+00 1.92673238689337767e+00 +1 1 6.28642454827198383e-01 1.59072934435342983e+00 1.72591461607902041e+00 1.93003133052151088e+00 diff --git a/test/data/output_RSVD/density.dat b/test/data/output_RSVD/density.dat new file mode 100644 index 00000000..49df18ae --- /dev/null +++ b/test/data/output_RSVD/density.dat @@ -0,0 +1,8 @@ +Energy = -6.19586141059654150e-01 0.00000000000000000e+00 +Sz = 6.24769001866300969e-03 -2.25123136949235366e-15 +Sx = -4.01056653321696516e-02 -6.43392851433750621e-16 +Sy = 4.94186616552133445e-02 8.96572849594022667e-17 +bond_hamiltonian = -6.19586141059654150e-01 5.82610064415346294e-16 +SzSz = -1.38599084645263937e-01 1.00053109826491253e-16 +SxSx = -2.78736112442398543e-01 9.41933653637062370e-16 +SySy = -2.02250943971991642e-01 -3.93820917008925646e-16 diff --git a/test/data/output_RSVD/onesite_obs.dat b/test/data/output_RSVD/onesite_obs.dat new file mode 100644 index 00000000..b0de798e --- /dev/null +++ b/test/data/output_RSVD/onesite_obs.dat @@ -0,0 +1,27 @@ +# The meaning of each column is the following: +# $1: op_group +# $2: site_index +# $3: real +# $4: imag +# The names of op_group are the following: +# 0: Sz +# 1: Sx +# 2: Sy +# -1: norm + +0 0 3.22162213461117258e-02 -3.12488859163444006e-16 +0 1 -1.30846898367870650e-02 6.46273259142999373e-15 +0 2 3.05859935940382202e-02 -3.45704268645410390e-17 +0 3 -2.47267650287108405e-02 -1.51205987833714233e-14 +1 0 2.32851779142767668e-01 -2.29317270277540293e-16 +1 1 -3.45291844588865304e-01 9.49404668869739572e-16 +1 2 -3.90945495777472618e-01 -6.51120601263360452e-16 +1 3 3.42962899894891649e-01 -2.64253820306384156e-15 +2 0 3.51988984805857941e-01 1.17062617806571853e-16 +2 1 -2.23025396767385670e-01 -8.39394956063888793e-16 +2 2 -1.47340746036399545e-01 -3.83650342784042602e-16 +2 3 2.16051804618780652e-01 1.46461182087896856e-15 +-1 0 7.32041456206711683e-01 1.88390969491081250e-14 +-1 1 7.34742666926989529e-01 1.92623694772464660e-14 +-1 2 7.39298899745712612e-01 1.89848137210901768e-14 +-1 3 7.21737171467045968e-01 1.88737914186276612e-14 diff --git a/test/data/output_RSVD/parameters.dat b/test/data/output_RSVD/parameters.dat new file mode 100644 index 00000000..abf60d48 --- /dev/null +++ b/test/data/output_RSVD/parameters.dat @@ -0,0 +1,39 @@ +simple_num_step = [100] +simple_tau = [0.01] +simple_inverse_lambda_cutoff = 1e-12 +simple_gauge_fix = 0 +simple_gauge_maxiter = 100 +simple_gauge_convergence_epsilon = 0.01 + +full_num_step = [1] +full_inverse_projector_cutoff = 1e-12 +full_inverse_precision = 1e-12 +full_convergence_epsilon = 1e-06 +full_iteration_max = 100 +full_gauge_fix = true +full_fastfullupdate = true + +ctm_dimension = 5 +ctm_inverse_projector_cutoff = 1e-12 +ctm_convergence_epsilon = 1e-06 +ctm_iteration_max = 100 +ctm_projector_corner = false +use_rsvd = true +rsvd_oversampling_factor = 2 +meanfield_env = false + +mode = ground state +simple +Lcor = 0 +seed = 11 +is_real = 0 +iszero_tol = 0 +measure = 1 +tensor_load_dir = +tensor_save_dir = +outdir = output_RSVD + +Lsub = [ 2 , 2 ] +skew = 0 + +start_datetime = 2023-12-27T10:08:59+09:00 diff --git a/test/data/output_RSVD/time.dat b/test/data/output_RSVD/time.dat new file mode 100644 index 00000000..4f3b784c --- /dev/null +++ b/test/data/output_RSVD/time.dat @@ -0,0 +1,5 @@ +time all = 2.33961 +time simple update = 0.870278 +time full update = 0.304127 +time environment = 0.930526 +time observable = 0.223058 diff --git a/test/data/output_RSVD/twosite_obs.dat b/test/data/output_RSVD/twosite_obs.dat new file mode 100644 index 00000000..ab19c285 --- /dev/null +++ b/test/data/output_RSVD/twosite_obs.dat @@ -0,0 +1,54 @@ +# The meaning of each column is the following: +# $1: op_group +# $2: source_site +# $3: dx +# $4: dy +# $5: real +# $6: imag +# The names of op_group are the following: +# 0: bond_hamiltonian +# 1: SzSz +# 2: SxSx +# 3: SySy +# -1: norm + +0 0 0 1 -2.60630499880987021e-01 -3.77554044563850987e-16 +0 0 1 0 -3.18036739953568015e-01 3.37491689939201927e-16 +0 1 0 1 -3.19277726261383843e-01 3.82829496040842891e-16 +0 1 1 0 -3.19951227842292463e-01 5.67000081301659176e-16 +0 2 0 1 -2.61779589763910303e-01 -9.84804763400151926e-17 +0 2 1 0 -3.37735337072606723e-01 -3.64491597856203834e-17 +0 3 0 1 -3.20981500125233687e-01 1.37778739134007502e-15 +0 3 1 0 -3.39951943338634266e-01 1.77815279729092824e-16 +1 0 0 1 -5.72781167132934838e-02 -5.87060075949757843e-17 +1 0 1 0 -7.32392667575661321e-02 2.38620163990432912e-16 +1 1 0 1 -6.85246833238848940e-02 1.78986261667761983e-16 +1 1 1 0 -7.40191966989294514e-02 6.94607627085453366e-17 +1 2 0 1 -5.77942520236587390e-02 1.20207100495835063e-17 +1 2 1 0 -7.67421777014239137e-02 -4.49032997642570905e-16 +1 3 0 1 -6.91966672009472761e-02 3.49976489413549227e-16 +1 3 1 0 -7.76019781613518089e-02 5.88870567136387422e-17 +2 0 0 1 -1.16811269234918344e-01 -1.00736489305436127e-16 +2 0 1 0 -1.23347186598962641e-01 3.69517206733165913e-16 +2 1 0 1 -1.50309983908081007e-01 7.05948234065969840e-16 +2 1 1 0 -1.23892345080040461e-01 3.86354694939097078e-16 +2 2 0 1 -1.17098972353629538e-01 5.10376678314275222e-17 +2 2 1 0 -1.66061271335565530e-01 7.97827639584375636e-16 +2 3 0 1 -1.50765352435800914e-01 1.27296357970013980e-15 +2 3 1 0 -1.66658068822595706e-01 2.84822080999510119e-16 +3 0 0 1 -8.65411139327752627e-02 -2.54004994759652003e-16 +3 0 1 0 -1.21450286597039395e-01 -2.68997362691640804e-16 +3 1 0 1 -1.00443059029417983e-01 -6.01564131086598017e-16 +3 1 1 0 -1.22039686063322536e-01 1.09121491143164088e-16 +3 2 0 1 -8.68863653866220331e-02 -9.92194252313746099e-17 +3 2 1 0 -9.49318880356172096e-02 -2.84707353904500902e-16 +3 3 0 1 -1.01019480488485455e-01 -2.02922094874033058e-16 +3 3 1 0 -9.56918963546866397e-02 2.70102033689325960e-17 +-1 0 0 1 5.26210166473529251e-01 1.61745616900077493e-14 +-1 0 1 0 5.34648522376578006e-01 1.46271883494364374e-14 +-1 1 0 1 5.25512620630181448e-01 1.40304434737004158e-14 +-1 1 1 0 5.18886729525302015e-01 1.43357548054723338e-14 +-1 2 0 1 5.19797007408131950e-01 1.60566004936413265e-14 +-1 2 1 0 5.34103204007730481e-01 1.35655375821386315e-14 +-1 3 0 1 5.19326965098691362e-01 1.32532873564628062e-14 +-1 3 1 0 5.18602453020453824e-01 1.35030875370034664e-14 From a39ed8504e2fdcbf36a96d45fe5c1a74969590ed Mon Sep 17 00:00:00 2001 From: Yuichi Motoyama Date: Thu, 21 Dec 2023 16:27:52 +0900 Subject: [PATCH 2/3] Fixed a bug in calculation of correlation length when CTM is shrinked --- src/arnoldi.cpp | 10 +++++++-- src/arnoldi.hpp | 3 +++ src/iTPS/core/ctm.cpp | 43 ++++++++++++++++-------------------- src/iTPS/transfer_matrix.cpp | 21 +++++++++++++++--- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/arnoldi.cpp b/src/arnoldi.cpp index a684433b..8c72a204 100644 --- a/src/arnoldi.cpp +++ b/src/arnoldi.cpp @@ -20,6 +20,7 @@ #include // for sqrt #include // for complex, ope... #include // for function +#include #include // for __vector_bas... #include "util/abs.hpp" @@ -32,7 +33,7 @@ namespace tenes { template Arnoldi::Arnoldi(size_t N, size_t maxvec) - : N(N), maxvec(maxvec), Q(maxvec + 1), H(Shape(maxvec + 1, maxvec)) { + : N(N), maxvec(maxvec), Q(maxvec + 1), H(Shape(maxvec + 1, maxvec)), mpisize(-1), mpirank(-1) { for (size_t i = 0; i < maxvec; ++i) { Q[i] = ptensor(mptensor::Shape(N)); } @@ -41,6 +42,8 @@ Arnoldi::Arnoldi(size_t N, size_t maxvec) template void Arnoldi::initialize(ptensor const& initial) { Q[0] = initial; + mpisize = Q[0].get_comm_size(); + mpirank = Q[0].get_comm_rank(); orthonormalize(0); } @@ -53,10 +56,14 @@ double norm(ptensor const& A) { template void Arnoldi::run(std::function A, size_t nev, int mindim, int maxiter, double rtol) { + if (mpisize < 0){ + throw std::runtime_error("Arnoldi::run: initialize() has not been called"); + } if (mindim < nev) { mindim = nev; } this->nev = nev; + int iter = 0; for (size_t k = 1; k <= nev; ++k) { A(Q[k], Q[k - 1]); orthonormalize(k); @@ -92,7 +99,6 @@ template void Arnoldi::orthonormalize(size_t k) { for (size_t j = 0; j < k; ++j) { auto xx = tensordot(conj(Q[j]), Q[k], {0}, {0}); - // std::cout << xx << std::endl; auto x = trace(xx, {}, {}); // auto x = trace(tensordot(conj(Q[j]), Q[k], {0}, {0}), {}, {}); H.set_value({j, k - 1}, x); diff --git a/src/arnoldi.hpp b/src/arnoldi.hpp index fbc25a03..e852fe29 100644 --- a/src/arnoldi.hpp +++ b/src/arnoldi.hpp @@ -65,6 +65,9 @@ class Arnoldi { std::vector Q; small_tensor H; + + int mpisize; + int mpirank; }; } // end of namespace tenes diff --git a/src/iTPS/core/ctm.cpp b/src/iTPS/core/ctm.cpp index 58f249d0..b68f52bf 100644 --- a/src/iTPS/core/ctm.cpp +++ b/src/iTPS/core/ctm.cpp @@ -240,28 +240,23 @@ void Calc_projector_left_block(const tensor &C1, const tensor &C4, Shape shape_col(t34, e56, t34); int cut = std::min(std::min(std::min(peps_parameters.CHI, e78 * t41 * t41), e12 * t12 * t12), e56 * t34 * t34); - /*int info ()= */ rsvd(m_row, m_col, shape_row, shape_col, U, s, VT, cut, static_cast(peps_parameters.RSVD_Oversampling_factor * cut)); double denom = s[0]; - std::vector s_c(cut); + std::vector s_c; + s_c.reserve(cut); for (int i = 0; i < cut; ++i) { if (s[i] / denom > peps_parameters.Inverse_projector_cut) { - s_c[i] = 1.0 / sqrt(s[i]); + s_c.push_back(1.0 / sqrt(s[i])); } else { - s_c[i] = 0.0; cut = i; break; } } - - // U.multiply_vector(s, 3); - // VT.multiply_vector(s, 0); - + tensor U_c = mptensor::slice(U, 3, 0, cut); tensor VT_c = mptensor::slice(VT, 0, 0, cut); - s_c.resize(cut); U_c.multiply_vector(s_c, 3); VT_c.multiply_vector(s_c, 0); @@ -275,19 +270,18 @@ void Calc_projector_left_block(const tensor &C1, const tensor &C4, tensor VT; std::vector s; - /* int info = */ svd(tensordot(LT, LB, Axes(1, 3, 5), Axes(0, 2, 4)), Axes(0, 1, 2), Axes(3, 4, 5), U, s, VT); double denom = s[0]; - // s_c.resize(e78); - int cut = std::min(std::min(std::min(peps_parameters.CHI, e78 * t41 * t41), e12 * t12 * t12), e56 * t34 * t34); - std::vector s_c(cut); + int cut = s.size(); + cut = std::min(cut, peps_parameters.CHI); + std::vector s_c; + s_c.reserve(cut); for (int i = 0; i < cut; ++i) { if (s[i] / denom > peps_parameters.Inverse_projector_cut) { - s_c[i] = 1.0 / sqrt(s[i]); + s_c.push_back(1.0 / sqrt(s[i])); } else { - s_c[i] = 0.0; cut = i; break; } @@ -342,6 +336,8 @@ void Calc_projector_updown_blocks( // int t34 = Tn3.shape()[0]; int t41 = Tn4.shape()[1]; + bool shrink_chi = true; + if (t41 != 1) { /* INFO:104 (2,3) Finish 72/104 script=[3, 0, 1, -1, 2, -1, 4, -1, -1] @@ -414,17 +410,16 @@ void Calc_projector_updown_blocks( Shape shape_col(t23, e34, t23); int cut = std::min(peps_parameters.CHI, e34 * t23 * t23); - /* int info = */ rsvd(m_row, m_col, shape_row, shape_col, U, s, VT, cut, static_cast(peps_parameters.RSVD_Oversampling_factor * cut)); double denom = s[0]; - std::vector s_c(cut); + std::vector s_c; + s_c.reserve(cut); for (int i = 0; i < cut; ++i) { if (s[i] / denom > peps_parameters.Inverse_projector_cut) { - s_c[i] = 1.0 / sqrt(s[i]); + s_c.push_back(1.0 / sqrt(s[i])); } else { - s_c[i] = 0.0; cut = i; break; } @@ -451,18 +446,18 @@ void Calc_projector_updown_blocks( tensor VT; std::vector s; - /* int info = */ svd(tensordot(R1, R2, Axes(3, 4, 5), Axes(3, 4, 5)), Axes(0, 1, 2), Axes(3, 4, 5), U, s, VT); double denom = s[0]; - int cut = std::min(peps_parameters.CHI, e34 * t23 * t23); - std::vector s_c(cut); + int cut = s.size(); + cut = std::min(cut, peps_parameters.CHI); + std::vector s_c; + s_c.reserve(cut); for (int i = 0; i < cut; ++i) { if (s[i] / denom > peps_parameters.Inverse_projector_cut) { - s_c[i] = 1.0 / sqrt(s[i]); + s_c.push_back(1.0 / sqrt(s[i])); } else { - s_c[i] = 0.0; cut = i; break; } diff --git a/src/iTPS/transfer_matrix.cpp b/src/iTPS/transfer_matrix.cpp index 07f6ea62..407d55ca 100644 --- a/src/iTPS/transfer_matrix.cpp +++ b/src/iTPS/transfer_matrix.cpp @@ -95,6 +95,9 @@ std::vector> TransferMatrix::eigenvalues( return eigvals; } + // for debug output + // const auto mpirank = this->Tn[0].get_comm_rank(); + if (N <= params.maxdim_dense_eigensolver) { ptensor matrix = dir == 0 ? matrix_horizontal(fixed_coord) : matrix_vertical(fixed_coord); @@ -160,20 +163,23 @@ template ptensor TransferMatrix_ctm::initial_vector(int dir, int fixed_coord, std::mt19937 &rng) const { const auto &lattice = this->lattice; - const size_t N = C1[0].shape()[0]; ptensor initial_vec; if (dir == 0) { int site = lattice.index(0, fixed_coord); ptensor left_top = C1[site]; ptensor left_bottom = C4[lattice.top(site)]; - initial_vec = reshape(tensordot(left_top, left_bottom, {0}, {1}), {N * N}); + const size_t CHI_top = left_top.shape()[1]; + const size_t CHI_bottom = left_bottom.shape()[0]; + initial_vec = reshape(tensordot(left_top, left_bottom, {0}, {1}), {CHI_top * CHI_bottom}); } else { int site = lattice.index(fixed_coord, 0); auto left_bottom = C4[site]; auto right_bottom = C3[lattice.left(site)]; + const size_t CHI_left = left_bottom.shape()[1]; + const size_t CHI_right = right_bottom.shape()[0]; initial_vec = - reshape(tensordot(left_bottom, right_bottom, {0}, {1}), {N * N}); + reshape(tensordot(left_bottom, right_bottom, {0}, {1}), {CHI_left * CHI_right}); } return initial_vec; } @@ -190,6 +196,10 @@ void TransferMatrix_ctm::matvec_horizontal(ptensor &outvec, const size_t CHI1 = eTb[s1].shape()[1]; outvec = reshape(invec, {CHI0, CHI1}); const size_t rank = eTt[0].rank(); + + // for debug output + // const auto mpirank = invec.get_comm_rank(); + if (rank == 3) { // iTPO for (int x = 0; x < lattice.LX; ++x) { @@ -244,6 +254,9 @@ void TransferMatrix_ctm::matvec_vertical(ptensor &outvec, const auto x_orig = x; outvec = reshape(invec, {CHI0, CHI1}); + // for debug output + // const auto mpirank = invec.get_comm_rank(); + const size_t rank = eTl[0].rank(); if (rank == 3) { @@ -520,6 +533,8 @@ ptensor TransferMatrix_mf::matrix_vertical(int x) const { template size_t TransferMatrix_ctm::dim(int dir, int fixed_coord) const { const auto &lattice = this->lattice; + // for debug output + const auto mpirank = this->Tn[0].get_comm_rank(); if(dir == 0){ const int s0 = lattice.index(0, fixed_coord); const int s1 = lattice.top(s0); From ea9e30eeac91d8b07790ee4c64fea14cccb4978e Mon Sep 17 00:00:00 2001 From: Yuichi Motoyama Date: Fri, 12 Jan 2024 11:39:36 +0900 Subject: [PATCH 3/3] enable to save tensors in time-evolution / finite-temperature --- src/iTPS/CMakeLists.txt | 1 + src/iTPS/main.cpp | 2 + src/iTPS/saveload_tensors.cpp | 348 ++++++++++++++++++++++++++++++++++ src/iTPS/tensors.cpp | 287 +--------------------------- 4 files changed, 357 insertions(+), 281 deletions(-) create mode 100644 src/iTPS/saveload_tensors.cpp diff --git a/src/iTPS/CMakeLists.txt b/src/iTPS/CMakeLists.txt index 649ed740..d260f22b 100644 --- a/src/iTPS/CMakeLists.txt +++ b/src/iTPS/CMakeLists.txt @@ -11,6 +11,7 @@ add_library( iTPS_impl STATIC iTPS.cpp tensors.cpp + saveload_tensors.cpp measure.cpp onesite_obs.cpp twosite_obs.cpp diff --git a/src/iTPS/main.cpp b/src/iTPS/main.cpp index 7bba3d75..20f6c82e 100644 --- a/src/iTPS/main.cpp +++ b/src/iTPS/main.cpp @@ -173,6 +173,7 @@ int run_timeevolution(MPI_Comm comm, PEPS_Parameters peps_parameters, onesite_operators, twosite_operators, multisite_operators, corparam, clength_param); tns.time_evolution(); + tns.save_tensors(); tns.summary(); return 0; } @@ -191,6 +192,7 @@ int run_finitetemperature(MPI_Comm comm, PEPS_Parameters peps_parameters, onesite_operators, twosite_operators, multisite_operators, corparam, clength_param); tns.finite_temperature(); + tns.save_tensors(); tns.summary(); return 0; } diff --git a/src/iTPS/saveload_tensors.cpp b/src/iTPS/saveload_tensors.cpp new file mode 100644 index 00000000..4000be90 --- /dev/null +++ b/src/iTPS/saveload_tensors.cpp @@ -0,0 +1,348 @@ +/* TeNeS - Massively parallel tensor network solver / +/ Copyright (C) 2019- The University of Tokyo */ + +/* This program 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. */ + +/* This program 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 this program. If not, see http://www.gnu.org/licenses/. */ + +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include + +#include "iTPS.hpp" + +#include "../tensor.hpp" + +#include "../printlevel.hpp" +#include "../util/file.hpp" +#include "../util/string.hpp" + +using std::size_t; + +namespace tenes { +namespace itps { + +template +void iTPS::save_tensors() const { + std::string const &save_dir = peps_parameters.tensor_save_dir; + if (save_dir.empty()) { + return; + } + { + // metadata + std::string filename = save_dir + "/params.dat"; + std::ofstream ofs(filename.c_str()); + + constexpr int tensor_format_version = 1; + ofs << tensor_format_version << " # Format_Version\n"; + ofs << N_UNIT << " # N_UNIT\n"; + ofs << CHI << " # CHI\n"; + for (int i = 0; i < N_UNIT; ++i) { + for (int j = 0; j < nleg; ++j) { + ofs << lattice.virtual_dims[i][j] << " "; + } + ofs << lattice.physical_dims[i] << " # Shape of Tn[" << i << "]\n"; + } + } + for (int i = 0; i < N_UNIT; ++i) { + std::string filename = save_dir + "/"; + std::string suffix = "_" + std::to_string(i) + ".dat"; + Tn[i].save((filename + "T" + suffix).c_str()); + eTt[i].save((filename + "Et" + suffix).c_str()); + eTr[i].save((filename + "Er" + suffix).c_str()); + eTb[i].save((filename + "Eb" + suffix).c_str()); + eTl[i].save((filename + "El" + suffix).c_str()); + C1[i].save((filename + "C1" + suffix).c_str()); + C2[i].save((filename + "C2" + suffix).c_str()); + C3[i].save((filename + "C3" + suffix).c_str()); + C4[i].save((filename + "C4" + suffix).c_str()); + } + if (mpirank == 0) { + for (int i = 0; i < N_UNIT; ++i) { + std::ofstream ofs(save_dir + "/lambda_" + std::to_string(i) + ".dat"); + for (int j = 0; j < nleg; ++j) { + for (int k = 0; k < lattice.virtual_dims[i][j]; ++k) { + ofs << lambda_tensor[i][j][k] << std::endl; + } + } + } + } + if (peps_parameters.print_level >= PrintLevel::info) { + std::cout << "Tensors saved in " << save_dir << std::endl; + } +} + +template +void iTPS::load_tensors() { + std::string const &load_dir = peps_parameters.tensor_load_dir; + + if (!util::isdir(load_dir)) { + std::string msg = load_dir + " does not exists."; + throw tenes::load_error(msg); + } + + int tensor_format_version = 0; + if (mpirank == 0) { + std::string filename = load_dir + "/params.dat"; + std::string line; + if (util::path_exists(filename)) { + std::ifstream ifs(filename.c_str()); + std::getline(ifs, line); + tensor_format_version = std::stoi(util::drop_comment(line)); + } + } + bcast(tensor_format_version, 0, comm); + if (tensor_format_version == 0) { + load_tensors_v0(); + } else if (tensor_format_version == 1) { + load_tensors_v1(); + } else { + std::stringstream ss; + ss << "ERROR: Unknown saved tensor format version: " + << tensor_format_version; + throw tenes::load_error(ss.str()); + } +} + +template +void load_tensor(ptensor &A, std::string const& name, std::string const& directory, int iunit){ + std::string filename = directory + "/" + name + "_" + std::to_string(iunit) + ".dat"; + ptensor temp; + temp.load(filename.c_str()); + if (A.rank() != temp.rank()){ + std::stringstream ss; + ss << "ERROR: rank mismatch in load_tensor: "; + ss << name << "[" << iunit << "] has " << A.rank() << " legs, but"; + ss << "loaded one has " << temp.rank() << " legs." << std::endl; + ss << "HINT: check the calculation mode. The number of legs differs between ground state calculation and finite temperature calculation."; + throw tenes::load_error(ss.str()); + } + A = resize_tensor(temp, A.shape()); +} + +template +void iTPS::load_tensors_v1() { + std::string const &load_dir = peps_parameters.tensor_load_dir; + + int loaded_CHI = 1; + std::vector> loaded_shape(N_UNIT, + std::vector(nleg + 1)); + if (mpirank == 0) { + std::string filename = load_dir + "/params.dat"; + std::string line; + std::ifstream ifs(filename.c_str()); + + std::getline(ifs, line); + const int format_version = std::stoi(util::drop_comment(line)); + assert(format_version == 1); + + std::getline(ifs, line); + const int loaded_N_UNIT = std::stoi(util::drop_comment(line)); + if (N_UNIT != loaded_N_UNIT) { + std::stringstream ss; + ss << "ERROR: N_UNIT is " << N_UNIT << " but loaded N_UNIT has " + << loaded_N_UNIT << std::endl; + throw tenes::load_error(ss.str()); + } + + std::getline(ifs, line); + loaded_CHI = std::stoi(util::drop_comment(line)); + if (CHI != loaded_CHI) { + if (peps_parameters.print_level >= PrintLevel::info) { + std::cout << "WARNING: parameters.ctm.dimension is " << CHI + << " but loaded tensors have CHI = " << loaded_CHI + << std::endl; + } + } + + for (int i = 0; i < N_UNIT; ++i) { + std::getline(ifs, line); + const auto shape = util::split(util::drop_comment(line)); + for (int j = 0; j < nleg; ++j) { + loaded_shape[i][j] = std::stoi(shape[j]); + const int vd_param = lattice.virtual_dims[i][j]; + if (vd_param != loaded_shape[i][j]) { + if (peps_parameters.print_level >= PrintLevel::info) { + std::cout << "WARNING: virtual dimension of the leg " << j + << " of the tensor " << i << " is " << vd_param + << " but loaded tensor has " << loaded_shape[i][j] + << std::endl; + } + } + } + loaded_shape[i][nleg] = std::stoi(shape[nleg]); + const int pdim = lattice.physical_dims[i]; + if (pdim != loaded_shape[i][nleg]) { + std::stringstream ss; + ss << "ERROR: dimension of the physical bond of the tensor " << i + << " is " << pdim << " but loaded tensor has " + << loaded_shape[i][nleg] << std::endl; + throw tenes::load_error(ss.str()); + } + } + } + for (int i = 0; i < N_UNIT; ++i) { + bcast(loaded_shape[i], 0, comm); + } + +// #define LOAD_TENSOR_(A, name) \ +// do { \ +// ptensor temp; \ +// temp.load((filename + name + suffix).c_str()); \ +// A = resize_tensor(temp, A.shape()); \ +// } while (false) + + for (int i = 0; i < N_UNIT; ++i) { + std::string filename = load_dir + "/"; + std::string suffix = "_" + std::to_string(i) + ".dat"; + + load_tensor(Tn[i], "T", load_dir, i); + load_tensor(eTl[i], "El", load_dir, i); + load_tensor(eTt[i], "Et", load_dir, i); + load_tensor(eTr[i], "Er", load_dir, i); + load_tensor(eTb[i], "Eb", load_dir, i); + load_tensor(C1[i], "C1", load_dir, i); + load_tensor(C2[i], "C2", load_dir, i); + load_tensor(C3[i], "C3", load_dir, i); + load_tensor(C4[i], "C4", load_dir, i); + // LOAD_TENSOR_(Tn[i], "T"); + // LOAD_TENSOR_(eTl[i], "El"); + // LOAD_TENSOR_(eTt[i], "Et"); + // LOAD_TENSOR_(eTr[i], "Er"); + // LOAD_TENSOR_(eTb[i], "Eb"); + // LOAD_TENSOR_(C1[i], "C1"); + // LOAD_TENSOR_(C2[i], "C2"); + // LOAD_TENSOR_(C3[i], "C3"); + // LOAD_TENSOR_(C4[i], "C4"); + } +// #undef LOAD_TENSOR_ + + std::vector ls; + if (mpirank == 0) { + for (int i = 0; i < N_UNIT; ++i) { + std::ifstream ifs(load_dir + "/lambda_" + std::to_string(i) + ".dat"); + for (int j = 0; j < nleg; ++j) { + for (int k = 0; k < loaded_shape[i][j]; ++k) { + double temp = 0.0; + ifs >> temp; + ls.push_back(temp); + } + } + } + } + bcast(ls, 0, comm); + int index = 0; + for (int i = 0; i < N_UNIT; ++i) { + const auto vdim = lattice.virtual_dims[i]; + for (int j = 0; j < nleg; ++j) { + lambda_tensor[i][j].clear(); + for (int k = 0; k < loaded_shape[i][j]; ++k) { + lambda_tensor[i][j].push_back(ls[index]); + ++index; + } + lambda_tensor[i][j].resize(vdim[j]); + } + } +} + +template +void iTPS::load_tensors_v0() { + using mptensor::Shape; + std::string const &load_dir = peps_parameters.tensor_load_dir; + + // load from the checkpoint + if (!util::isdir(load_dir)) { + std::string msg = load_dir + " does not exists."; + throw tenes::load_error(msg); + } + for (int i = 0; i < N_UNIT; ++i) { + std::string filename = load_dir + "/"; + std::string suffix = "_" + std::to_string(i) + ".dat"; + Tn[i].load((filename + "T" + suffix).c_str()); + eTt[i].load((filename + "Et" + suffix).c_str()); + eTr[i].load((filename + "Er" + suffix).c_str()); + eTb[i].load((filename + "Eb" + suffix).c_str()); + eTl[i].load((filename + "El" + suffix).c_str()); + C1[i].load((filename + "C1" + suffix).c_str()); + C2[i].load((filename + "C2" + suffix).c_str()); + C3[i].load((filename + "C3" + suffix).c_str()); + C4[i].load((filename + "C4" + suffix).c_str()); + } + std::vector ls; + if (mpirank == 0) { + for (int i = 0; i < N_UNIT; ++i) { + const auto vdim = lattice.virtual_dims[i]; + std::ifstream ifs(load_dir + "/lambda_" + std::to_string(i) + ".dat"); + for (int j = 0; j < nleg; ++j) { + for (int k = 0; k < vdim[j]; ++k) { + double temp = 0.0; + ifs >> temp; + ls.push_back(temp); + } + } + } + } + bcast(ls, 0, comm); + int index = 0; + for (int i = 0; i < N_UNIT; ++i) { + const auto vdim = lattice.virtual_dims[i]; + for (int j = 0; j < nleg; ++j) { + for (int k = 0; k < vdim[j]; ++k) { + lambda_tensor[i][j][k] = ls[index]; + ++index; + } + } + } + + // overwrite dimensions + const Shape Cshape = C1[0].shape(); + if (CHI != Cshape[0]) { + if (peps_parameters.print_level >= PrintLevel::info) { + std::cout << "WARNING: parameters.ctm.dimension is " << CHI + << " but loaded tensors have CHI = " << Cshape[0] << std::endl; + } + } + for (int i = 0; i < N_UNIT; ++i) { + const Shape Tshape = Tn[i].shape(); + const int pdim = lattice.physical_dims[i]; + if (pdim != Tshape[4]) { + std::stringstream ss; + ss << "ERROR: dimension of the physical bond of the tensor " << i + << " is " << pdim << " but loaded tensor has " << Tshape[4] + << std::endl; + throw tenes::input_error(ss.str()); + } + + for (int l = 0; l < nleg; ++l) { + const int vd_param = lattice.virtual_dims[i][l]; + const int vd_loaded = Tshape[l]; + if (vd_param != vd_loaded) { + if (peps_parameters.print_level >= PrintLevel::info) { + std::cout << "WARNING: virtual dimension of the leg " << l + << " of the tensor " << i << " is " << vd_param + << " but loaded tensor has " << vd_loaded << std::endl; + } + } + } + } +} + +// template specialization +template class iTPS; +template class iTPS; + +} // namespace itps +} // namespace tenes diff --git a/src/iTPS/tensors.cpp b/src/iTPS/tensors.cpp index 30fb17e7..990248a7 100644 --- a/src/iTPS/tensors.cpp +++ b/src/iTPS/tensors.cpp @@ -54,7 +54,8 @@ void iTPS::initialize_tensors() { const auto pdim = lattice.physical_dims[i]; const auto vdim = lattice.virtual_dims[i]; - Tn.push_back(ptensor(comm, Shape(vdim[0], vdim[1], vdim[2], vdim[3], pdim))); + Tn.push_back( + ptensor(comm, Shape(vdim[0], vdim[1], vdim[2], vdim[3], pdim))); eTt.push_back(ptensor(comm, Shape(CHI, CHI, vdim[1], vdim[1]))); eTr.push_back(ptensor(comm, Shape(CHI, CHI, vdim[2], vdim[2]))); eTb.push_back(ptensor(comm, Shape(CHI, CHI, vdim[3], vdim[3]))); @@ -135,283 +136,6 @@ void iTPS::initialize_tensors() { } // end of else part of if(load_dir.empty()) } -template -void iTPS::save_tensors() const { - std::string const &save_dir = peps_parameters.tensor_save_dir; - if (save_dir.empty()) { - return; - } - { - // metadata - std::string filename = save_dir + "/params.dat"; - std::ofstream ofs(filename.c_str()); - - constexpr int tensor_format_version = 1; - ofs << tensor_format_version << " # Format_Version\n"; - ofs << N_UNIT << " # N_UNIT\n"; - ofs << CHI << " # CHI\n"; - for (int i = 0; i < N_UNIT; ++i) { - for (int j = 0; j < nleg; ++j) { - ofs << lattice.virtual_dims[i][j] << " "; - } - ofs << lattice.physical_dims[i] << " # Shape of Tn[" << i << "]\n"; - } - } - for (int i = 0; i < N_UNIT; ++i) { - std::string filename = save_dir + "/"; - std::string suffix = "_" + std::to_string(i) + ".dat"; - Tn[i].save((filename + "T" + suffix).c_str()); - eTt[i].save((filename + "Et" + suffix).c_str()); - eTr[i].save((filename + "Er" + suffix).c_str()); - eTb[i].save((filename + "Eb" + suffix).c_str()); - eTl[i].save((filename + "El" + suffix).c_str()); - C1[i].save((filename + "C1" + suffix).c_str()); - C2[i].save((filename + "C2" + suffix).c_str()); - C3[i].save((filename + "C3" + suffix).c_str()); - C4[i].save((filename + "C4" + suffix).c_str()); - } - if (mpirank == 0) { - for (int i = 0; i < N_UNIT; ++i) { - std::ofstream ofs(save_dir + "/lambda_" + std::to_string(i) + ".dat"); - for (int j = 0; j < nleg; ++j) { - for (int k = 0; k < lattice.virtual_dims[i][j]; ++k) { - ofs << lambda_tensor[i][j][k] << std::endl; - } - } - } - } - if (peps_parameters.print_level >= PrintLevel::info) { - std::cout << "Tensors saved in " << save_dir << std::endl; - } -} - -template -void iTPS::load_tensors() { - std::string const &load_dir = peps_parameters.tensor_load_dir; - - if (!util::isdir(load_dir)) { - std::string msg = load_dir + " does not exists."; - throw tenes::load_error(msg); - } - - int tensor_format_version = 0; - if (mpirank == 0) { - std::string filename = load_dir + "/params.dat"; - std::string line; - if (util::path_exists(filename)) { - std::ifstream ifs(filename.c_str()); - std::getline(ifs, line); - tensor_format_version = std::stoi(util::drop_comment(line)); - } - } - bcast(tensor_format_version, 0, comm); - if (tensor_format_version == 0) { - load_tensors_v0(); - } else if (tensor_format_version == 1) { - load_tensors_v1(); - } else { - std::stringstream ss; - ss << "ERROR: Unknown checkpoint format version: " << tensor_format_version; - throw tenes::load_error(ss.str()); - } -} - -template -void iTPS::load_tensors_v1() { - std::string const &load_dir = peps_parameters.tensor_load_dir; - - int loaded_CHI = 1; - std::vector> loaded_shape(N_UNIT, - std::vector(nleg + 1)); - if (mpirank == 0) { - std::string filename = load_dir + "/params.dat"; - std::string line; - std::ifstream ifs(filename.c_str()); - std::getline(ifs, line); - - std::getline(ifs, line); - const int loaded_N_UNIT = std::stoi(util::drop_comment(line)); - if (N_UNIT != loaded_N_UNIT) { - std::stringstream ss; - ss << "ERROR: N_UNIT is " << N_UNIT << " but loaded N_UNIT has " - << loaded_N_UNIT << std::endl; - throw tenes::load_error(ss.str()); - } - - std::getline(ifs, line); - loaded_CHI = std::stoi(util::drop_comment(line)); - if (CHI != loaded_CHI) { - if (peps_parameters.print_level >= PrintLevel::info) { - std::cout << "WARNING: parameters.ctm.dimension is " << CHI - << " but loaded tensors have CHI = " << loaded_CHI - << std::endl; - } - } - - for (int i = 0; i < N_UNIT; ++i) { - std::getline(ifs, line); - const auto shape = util::split(util::drop_comment(line)); - for (int j = 0; j < nleg; ++j) { - loaded_shape[i][j] = std::stoi(shape[j]); - const int vd_param = lattice.virtual_dims[i][j]; - if (vd_param != loaded_shape[i][j]) { - if (peps_parameters.print_level >= PrintLevel::info) { - std::cout << "WARNING: virtual dimension of the leg " << j - << " of the tensor " << i << " is " << vd_param - << " but loaded tensor has " << loaded_shape[i][j] - << std::endl; - } - } - } - loaded_shape[i][nleg] = std::stoi(shape[nleg]); - const int pdim = lattice.physical_dims[i]; - if (pdim != loaded_shape[i][nleg]) { - std::stringstream ss; - ss << "ERROR: dimension of the physical bond of the tensor " << i - << " is " << pdim << " but loaded tensor has " - << loaded_shape[i][nleg] << std::endl; - throw tenes::load_error(ss.str()); - } - } - } - for (int i = 0; i < N_UNIT; ++i) { - bcast(loaded_shape[i], 0, comm); - } - -#define LOAD_TENSOR_(A, name) \ - do { \ - ptensor temp; \ - temp.load((filename + name + suffix).c_str()); \ - A = resize_tensor(temp, A.shape()); \ - } while (false) - - for (int i = 0; i < N_UNIT; ++i) { - std::string filename = load_dir + "/"; - std::string suffix = "_" + std::to_string(i) + ".dat"; - - LOAD_TENSOR_(Tn[i], "T"); - LOAD_TENSOR_(eTl[i], "El"); - LOAD_TENSOR_(eTt[i], "Et"); - LOAD_TENSOR_(eTr[i], "Er"); - LOAD_TENSOR_(eTb[i], "Eb"); - LOAD_TENSOR_(C1[i], "C1"); - LOAD_TENSOR_(C2[i], "C2"); - LOAD_TENSOR_(C3[i], "C3"); - LOAD_TENSOR_(C4[i], "C4"); - } -#undef LOAD_TENSOR_ - - std::vector ls; - if (mpirank == 0) { - for (int i = 0; i < N_UNIT; ++i) { - std::ifstream ifs(load_dir + "/lambda_" + std::to_string(i) + ".dat"); - for (int j = 0; j < nleg; ++j) { - for (int k = 0; k < loaded_shape[i][j]; ++k) { - double temp = 0.0; - ifs >> temp; - ls.push_back(temp); - } - } - } - } - bcast(ls, 0, comm); - int index = 0; - for (int i = 0; i < N_UNIT; ++i) { - const auto vdim = lattice.virtual_dims[i]; - for (int j = 0; j < nleg; ++j) { - lambda_tensor[i][j].clear(); - for (int k = 0; k < loaded_shape[i][j]; ++k) { - lambda_tensor[i][j].push_back(ls[index]); - ++index; - } - lambda_tensor[i][j].resize(vdim[j]); - } - } -} - -template -void iTPS::load_tensors_v0() { - using mptensor::Shape; - std::string const &load_dir = peps_parameters.tensor_load_dir; - - // load from the checkpoint - if (!util::isdir(load_dir)) { - std::string msg = load_dir + " does not exists."; - throw tenes::load_error(msg); - } - for (int i = 0; i < N_UNIT; ++i) { - std::string filename = load_dir + "/"; - std::string suffix = "_" + std::to_string(i) + ".dat"; - Tn[i].load((filename + "T" + suffix).c_str()); - eTt[i].load((filename + "Et" + suffix).c_str()); - eTr[i].load((filename + "Er" + suffix).c_str()); - eTb[i].load((filename + "Eb" + suffix).c_str()); - eTl[i].load((filename + "El" + suffix).c_str()); - C1[i].load((filename + "C1" + suffix).c_str()); - C2[i].load((filename + "C2" + suffix).c_str()); - C3[i].load((filename + "C3" + suffix).c_str()); - C4[i].load((filename + "C4" + suffix).c_str()); - } - std::vector ls; - if (mpirank == 0) { - for (int i = 0; i < N_UNIT; ++i) { - const auto vdim = lattice.virtual_dims[i]; - std::ifstream ifs(load_dir + "/lambda_" + std::to_string(i) + ".dat"); - for (int j = 0; j < nleg; ++j) { - for (int k = 0; k < vdim[j]; ++k) { - double temp = 0.0; - ifs >> temp; - ls.push_back(temp); - } - } - } - } - bcast(ls, 0, comm); - int index = 0; - for (int i = 0; i < N_UNIT; ++i) { - const auto vdim = lattice.virtual_dims[i]; - for (int j = 0; j < nleg; ++j) { - for (int k = 0; k < vdim[j]; ++k) { - lambda_tensor[i][j][k] = ls[index]; - ++index; - } - } - } - - // overwrite dimensions - const Shape Cshape = C1[0].shape(); - if (CHI != Cshape[0]) { - if (peps_parameters.print_level >= PrintLevel::info) { - std::cout << "WARNING: parameters.ctm.dimension is " << CHI - << " but loaded tensors have CHI = " << Cshape[0] << std::endl; - } - } - for (int i = 0; i < N_UNIT; ++i) { - const Shape Tshape = Tn[i].shape(); - const int pdim = lattice.physical_dims[i]; - if (pdim != Tshape[4]) { - std::stringstream ss; - ss << "ERROR: dimension of the physical bond of the tensor " << i - << " is " << pdim << " but loaded tensor has " << Tshape[4] - << std::endl; - throw tenes::input_error(ss.str()); - } - - for (int l = 0; l < nleg; ++l) { - const int vd_param = lattice.virtual_dims[i][l]; - const int vd_loaded = Tshape[l]; - if (vd_param != vd_loaded) { - if (peps_parameters.print_level >= PrintLevel::info) { - std::cout << "WARNING: virtual dimension of the leg " << l - << " of the tensor " << i << " is " << vd_param - << " but loaded tensor has " << vd_loaded << std::endl; - } - } - } - } -} - - template void iTPS::initialize_tensors_density() { using mptensor::Shape; @@ -431,7 +155,8 @@ void iTPS::initialize_tensors_density() { const auto pdim = lattice.physical_dims[i]; const auto vdim = lattice.virtual_dims[i]; - Tn.push_back(ptensor(comm, Shape(vdim[0], vdim[1], vdim[2], vdim[3], pdim, pdim))); + Tn.push_back( + ptensor(comm, Shape(vdim[0], vdim[1], vdim[2], vdim[3], pdim, pdim))); eTt.push_back(ptensor(comm, Shape(CHI, CHI, vdim[1]))); eTr.push_back(ptensor(comm, Shape(CHI, CHI, vdim[2]))); eTb.push_back(ptensor(comm, Shape(CHI, CHI, vdim[3]))); @@ -469,7 +194,8 @@ void iTPS::initialize_tensors_density() { for (int n = 0; n < Tn[i].local_size(); ++n) { index = Tn[i].global_index(n); - if (index[0] == 0 && index[1] == 0 && index[2] == 0 && index[3] == 0 && index[4] == index[5]) { + if (index[0] == 0 && index[1] == 0 && index[2] == 0 && index[3] == 0 && + index[4] == index[5]) { Tn[i].set_value(index, to_tensor_type(1.0)); } else { Tn[i].set_value(index, to_tensor_type(0.0)); @@ -485,7 +211,6 @@ void iTPS::initialize_tensors_density() { } // end of else part of if(load_dir.empty()) } - // template specialization template class iTPS; template class iTPS;