diff --git a/CHANGELOG.md b/CHANGELOG.md index 0867a5aa4..9dd789df6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Release 3.1.1 + +- Fixed bug raising the "pre-existing term" message when constructing the MPO +- Enhancement of the overlap calculation in MPS-SI + ## Release 3.1.0 - Added support for TD-DMRG with time-independent Hamiltonian diff --git a/dmrg/CMakeLists.txt b/dmrg/CMakeLists.txt index ac081a92d..4b486be69 100644 --- a/dmrg/CMakeLists.txt +++ b/dmrg/CMakeLists.txt @@ -393,7 +393,9 @@ if(QCMAQUIS_TESTS) add_test(NAME Test_Relativistic COMMAND test_rel) add_test(NAME Test_Integral_Map COMMAND test_integral_map) add_test(NAME Test_HiRDM COMMAND test_hirdm) - add_test(NAME Test_MPS_MPO_Ops COMMAND test_mps_mpo_ops) + add_test(NAME Test_MPS_MPO_Ops_TwoU1 COMMAND test_mps_mpo_ops_TwoU1) + add_test(NAME Test_MPS_MPO_Ops_Electronic COMMAND test_mps_mpo_ops_electronic) + add_test(NAME Test_MPS_Overlap_Electronic COMMAND test_mps_overlap_electronic) add_test(NAME Test_SiteProblem COMMAND test_siteproblem) add_test(NAME Test_MPS_Join COMMAND test_mpsjoin) add_test(NAME Test_Wigner COMMAND test_wigner) diff --git a/dmrg/framework/dmrg/CMakeLists.txt b/dmrg/framework/dmrg/CMakeLists.txt index 746fa22ce..ff0adb957 100644 --- a/dmrg/framework/dmrg/CMakeLists.txt +++ b/dmrg/framework/dmrg/CMakeLists.txt @@ -28,10 +28,6 @@ foreach(SYMM ${BUILD_SYMMETRIES}) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TRIAL_INCLUDE_FACTORY}") add_line_to(MAQUIS_INCLUDE_FACTORIES_${GROUP_NAME} "#include \"dmrg/${TRIAL_INCLUDE_FACTORY}\"") endif() - set(TRIAL_INCLUDE_FACTORY "models/continuum/factory_${SYMM_SUFFIX}.ipp") - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TRIAL_INCLUDE_FACTORY}") - add_line_to(MAQUIS_INCLUDE_FACTORIES_${GROUP_NAME} "#include \"dmrg/${TRIAL_INCLUDE_FACTORY}\"") - endif() endforeach(SYMM) configure_symm_file("models/model_factory_symm/model_factory_tpl.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/models/model_factory_symm/model_factory_{SYMM}.cpp" CMAKE_SYMM_GROUP) diff --git a/dmrg/framework/dmrg/block_matrix/block_matrix_algorithms.h b/dmrg/framework/dmrg/block_matrix/block_matrix_algorithms.h index 2adcfe250..d7923f2fa 100644 --- a/dmrg/framework/dmrg/block_matrix/block_matrix_algorithms.h +++ b/dmrg/framework/dmrg/block_matrix/block_matrix_algorithms.h @@ -45,52 +45,46 @@ #include "dmrg/utils/parallel.hpp" +/** @brief Struct storing the results of an MPS truncation */ struct truncation_results { std::size_t bond_dimension; // new bond dimension double truncated_weight; // sum of discarded eigenvalues (square of singuler values) double truncated_fraction; // sum of discarded singular values double smallest_ev; // smallest eigenvalue kept + /** @brief Empty constructor */ truncation_results() { } + /** @brief Constructor taking input data */ truncation_results(std::size_t m, double tw, double tf, double se) - : bond_dimension(m) - , truncated_weight(tw) - , truncated_fraction(tf) - , smallest_ev(se) + : bond_dimension(m), truncated_weight(tw), truncated_fraction(tf), smallest_ev(se) { } }; -//template +/** @brief Multiplication between block matrices */ template -void gemm(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - const Scheduler& scheduler = Scheduler()) +void gemm(block_matrix const & A, block_matrix const & B, + block_matrix & C, const Scheduler& scheduler = Scheduler()) { + // Types definition + using charge = typename SymmGroup::charge; + using const_iterator = typename DualIndex::const_iterator; + // C.clear(); assert(B.basis().is_sorted()); - - typedef typename SymmGroup::charge charge; - typedef typename DualIndex::const_iterator const_iterator; const_iterator B_begin = B.basis().begin(); const_iterator B_end = B.basis().end(); - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - + for (int k = 0; k < A.n_blocks(); ++k) { charge ar = A.basis().right_charge(k); const_iterator it = B.basis().left_lower_bound(ar); - - for ( ; it != B_end && it->lc == ar; ++it) - { - std::size_t matched_block = std::distance(B_begin, it); + for ( ; it != B_end && it->lc == ar; ++it) { + auto matched_block = std::distance(B_begin, it); Matrix3 tmp(num_rows(A[k]), it->rs); - parallel::guard proc(scheduler(k)); gemm(A[k], B[matched_block], tmp); C.match_and_add_block(tmp, A.basis().left_charge(k), it->rc); } } - if(scheduler.propagate()){ Index B_left_basis = B.left_basis(); C.size_index.resize(C.n_blocks()); // propagating A size_index onto C - otherwise might C.index_sizes(); @@ -102,6 +96,7 @@ void gemm(block_matrix const & A, } } +/** @brief Wrapper around gemm that avoids setting the scheduler */ template void gemm(block_matrix const & A, block_matrix const & B, @@ -110,8 +105,18 @@ void gemm(block_matrix const & A, gemm(A, B, C, parallel::scheduler_nop()); } -// ref_left_basis: basis of B equivalent in the bra for contractions where bra != ket -// for bra == ket it is equal to the left basis of B +/** + * @brief Matrix-matrix multiplication with left basis trimming. + * + * In addition to performing the matrix-matrix multiplication, this routine + * also "trims" the row index by keeping only the blocks that are present + * in [ref_left_basis]. + * + * @param A First input matrix + * @param B Second input matrix + * @param C Output matrix + * @param ref_left_basis Index used as a reference for trimming + */ template void gemm_trim_left(block_matrix const & A, block_matrix const & B, @@ -120,29 +125,33 @@ void gemm_trim_left(block_matrix const & A, { parallel::scheduler_size_indexed scheduler(A); C.clear(); - - typedef typename SymmGroup::charge charge; Index B_left_basis = B.left_basis(); for (std::size_t k = 0; k < A.n_blocks(); ++k) { - std::size_t matched_block = B_left_basis.position(A.basis().right_charge(k)); - + auto matched_block = B_left_basis.position(A.basis().right_charge(k)); // Match right basis of A with left basis of B if ( matched_block == B.n_blocks() ) continue; - if ( !ref_left_basis.has(A.basis().left_charge(k)) ) continue; - - std::size_t new_block = C.insert_block(new Matrix3(num_rows(A[k]), num_cols(B[matched_block])), - A.basis().left_charge(k), B.basis().right_charge(matched_block)); - + auto new_block = C.insert_block(new Matrix3(num_rows(A[k]), num_cols(B[matched_block])), + A.basis().left_charge(k), B.basis().right_charge(matched_block)); parallel::guard proc(scheduler(k)); gemm(A[k], B[matched_block], C[new_block]); } } -// ref_right_basis: basis of A equivalent in the bra for contractions where bra != ket -// for bra == ket it is equal to the right basis of A +/** + * @brief Matrix-matrix multiplication with right basis trimming. + * + * In addition to performing the matrix-matrix multiplication, this routine + * also "trims" the column index by keeping only the blocks that are present + * in [ref_right_basis]. + * + * @param A First input matrix + * @param B Second input matrix + * @param C Output matrix + * @param ref_left_basis Index used as a reference for trimming + */ template void gemm_trim_right(block_matrix const & A, block_matrix const & B, @@ -154,21 +163,16 @@ void gemm_trim_right(block_matrix const & A, typedef typename SymmGroup::charge charge; Index A_right_basis = A.right_basis(); - for (std::size_t k = 0; k < B.n_blocks(); ++k) { - std::size_t matched_block = A_right_basis.position(B.basis().left_charge(k)); - + for (int k = 0; k < B.n_blocks(); ++k) { + auto matched_block = A_right_basis.position(B.basis().left_charge(k)); // Match right basis of A with left basis of B if ( matched_block == A.n_blocks() ) continue; - // Also match right_basis of bra with B.right_basis() - if ( !ref_right_basis.has(B.basis().right_charge(k)) ) continue; - std::size_t new_block = C.insert_block(new Matrix3(num_rows(A[matched_block]), num_cols(B[k])), - A.basis().left_charge(matched_block), B.basis().right_charge(k)); - + A.basis().left_charge(matched_block), B.basis().right_charge(k)); parallel::guard proc(scheduler(k)); gemm(A[matched_block], B[k], C[new_block]); } diff --git a/dmrg/framework/dmrg/models/chem/2u1/chem_helper.h b/dmrg/framework/dmrg/models/chem/2u1/chem_helper.h index 8b164a5c2..3fe59a2d9 100644 --- a/dmrg/framework/dmrg/models/chem/2u1/chem_helper.h +++ b/dmrg/framework/dmrg/models/chem/2u1/chem_helper.h @@ -101,8 +101,8 @@ namespace detail { term_descriptor term; term.is_fermionic = false; term.coeff = scale * ptag1.second * ptag2.second; - term.push_back(boost::make_tuple(p1, ptag1.first)); - term.push_back(boost::make_tuple(p2, ptag2.first)); + term.push_back(std::make_pair(p1, ptag1.first)); + term.push_back(std::make_pair(p2, ptag2.first)); IndexTuple id(p1, p2, ptag1.first, ptag2.first); diff --git a/dmrg/framework/dmrg/models/chem/2u1/model.hpp b/dmrg/framework/dmrg/models/chem/2u1/model.hpp index 76f7c213e..c4e27c304 100644 --- a/dmrg/framework/dmrg/models/chem/2u1/model.hpp +++ b/dmrg/framework/dmrg/models/chem/2u1/model.hpp @@ -211,7 +211,7 @@ void qc_model::create_terms() term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(0, ident[lat.get_prop("type", 0)])); + term.push_back( std::make_pair(0, ident[lat.get_prop("type", 0)])); this->terms_.push_back(term); used_elements[m] += 1; @@ -222,13 +222,13 @@ void qc_model::create_terms() { term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(i, count_up[lat.get_prop("type", i)])); + term.push_back( std::make_pair(i, count_up[lat.get_prop("type", i)])); this->terms_.push_back(term); } { term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(i, count_down[lat.get_prop("type", i)])); + term.push_back( std::make_pair(i, count_down[lat.get_prop("type", i)])); this->terms_.push_back(term); } @@ -260,7 +260,7 @@ void qc_model::create_terms() term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back(boost::make_tuple(i, docc[lat.get_prop("type", 0)])); + term.push_back(std::make_pair(i, docc[lat.get_prop("type", 0)])); this->terms_.push_back(term); used_elements[m] += 1; diff --git a/dmrg/framework/dmrg/models/chem/2u1/term_maker.h b/dmrg/framework/dmrg/models/chem/2u1/term_maker.h index 5a2203781..c648d516b 100644 --- a/dmrg/framework/dmrg/models/chem/2u1/term_maker.h +++ b/dmrg/framework/dmrg/models/chem/2u1/term_maker.h @@ -5,7 +5,6 @@ * Copyright (C) 2015 Laboratory for Physical Chemistry, ETH Zurich * 2012-2015 by Sebastian Keller * - * * This software is part of the ALPS Applications, published under the ALPS * Application License; you can use, redistribute it and/or modify it under * the terms of the license, either version 1 or (at your option) any later @@ -39,10 +38,9 @@ struct TermMaker { typedef typename term_descriptor::value_type pos_op_t; typedef typename S::subcharge sc_t; - static bool compare_tag(pos_op_t p1, - pos_op_t p2) + static bool compare_tag(const pos_op_t& p1, const pos_op_t& p2) { - return boost::tuples::get<0>(p1) < boost::tuples::get<0>(p2); + return p1.first < p2.first; } static term_descriptor two_term(bool sign, std::vector const & fill_op, value_type scale, pos_t i, pos_t j, @@ -53,8 +51,8 @@ struct TermMaker { term_descriptor term; term.is_fermionic = sign; term.coeff = scale; - term.push_back(boost::make_tuple(i, op1[lat.get_prop("type", i)])); - term.push_back(boost::make_tuple(j, op2[lat.get_prop("type", j)])); + term.push_back(std::make_pair(i, op1[lat.get_prop("type", i)])); + term.push_back(std::make_pair(j, op2[lat.get_prop("type", j)])); return term; } @@ -70,14 +68,14 @@ struct TermMaker { std::pair ptag; if (i < j) { ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", i)], op1[lat.get_prop("type", i)]); - term.push_back(boost::make_tuple(i, ptag.first)); - term.push_back(boost::make_tuple(j, op2[lat.get_prop("type", j)])); + term.push_back(std::make_pair(i, ptag.first)); + term.push_back(std::make_pair(j, op2[lat.get_prop("type", j)])); term.coeff *= ptag.second; } else { ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", j)], op2[lat.get_prop("type", j)]); - term.push_back(boost::make_tuple(i, op1[lat.get_prop("type", i)])); - term.push_back(boost::make_tuple(j, ptag.first)); + term.push_back(std::make_pair(i, op1[lat.get_prop("type", i)])); + term.push_back(std::make_pair(j, ptag.first)); term.coeff *= -ptag.second; } return term; @@ -99,14 +97,14 @@ struct TermMaker { std::pair ptag; if (i < j) { ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", i)], pre_ptag.first); - term.push_back(boost::make_tuple(i, ptag.first)); - term.push_back(boost::make_tuple(j, op3[lat.get_prop("type", j)])); + term.push_back(std::make_pair(i, ptag.first)); + term.push_back(std::make_pair(j, op3[lat.get_prop("type", j)])); term.coeff *= ptag.second * pre_ptag.second; } else { ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", j)], op3[lat.get_prop("type", j)]); - term.push_back(boost::make_tuple(i, pre_ptag.first)); - term.push_back(boost::make_tuple(j, ptag.first)); + term.push_back(std::make_pair(i, pre_ptag.first)); + term.push_back(std::make_pair(j, ptag.first)); term.coeff *= -ptag.second * pre_ptag.second; } return term; @@ -155,9 +153,9 @@ struct TermMaker { } std::vector sterm; - sterm.push_back( boost::make_tuple(pb, boson_op) ); - sterm.push_back( boost::make_tuple(p1, op1) ); - sterm.push_back( boost::make_tuple(p2, op2) ); + sterm.push_back( std::make_pair(pb, boson_op) ); + sterm.push_back( std::make_pair(p1, op1) ); + sterm.push_back( std::make_pair(p2, op2) ); std::sort(sterm.begin(), sterm.end(), compare_tag); term.push_back(sterm[0]); @@ -186,18 +184,18 @@ struct TermMaker { if(idx[c1] > idx[c2]) inv_count++; std::vector sterm; - sterm.push_back(boost::make_tuple(i, op_i[lat.get_prop("type", i)])); - sterm.push_back(boost::make_tuple(j, op_j[lat.get_prop("type", j)])); - sterm.push_back(boost::make_tuple(k, op_k[lat.get_prop("type", k)])); - sterm.push_back(boost::make_tuple(l, op_l[lat.get_prop("type", l)])); + sterm.push_back(std::make_pair(i, op_i[lat.get_prop("type", i)])); + sterm.push_back(std::make_pair(j, op_j[lat.get_prop("type", j)])); + sterm.push_back(std::make_pair(k, op_k[lat.get_prop("type", k)])); + sterm.push_back(std::make_pair(l, op_l[lat.get_prop("type", l)])); std::sort(sterm.begin(), sterm.end(), compare_tag); std::pair ptag; - ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", boost::tuples::get<0>(sterm[0]))], boost::tuples::get<1>(sterm[0])); - boost::tuples::get<1>(sterm[0]) = ptag.first; + ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", sterm[0].first)], sterm[0].second); + sterm[0].second = ptag.first; term.coeff *= ptag.second; - ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", boost::tuples::get<0>(sterm[2]))], boost::tuples::get<1>(sterm[2])); - boost::tuples::get<1>(sterm[2]) = ptag.first; + ptag = op_table->get_product_tag(fill_op[lat.get_prop("type", sterm[2].first)], sterm[2].second); + sterm[2].second = ptag.first; term.coeff *= ptag.second; if (inv_count % 2) diff --git a/dmrg/framework/dmrg/models/chem/rel/model.hpp b/dmrg/framework/dmrg/models/chem/rel/model.hpp index 4c24bbbec..b27566160 100644 --- a/dmrg/framework/dmrg/models/chem/rel/model.hpp +++ b/dmrg/framework/dmrg/models/chem/rel/model.hpp @@ -114,7 +114,7 @@ void rel_qc_model::create_terms() term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(0, ident[lat.get_prop("type", 0)]) ); + term.push_back( std::make_pair(0, ident[lat.get_prop("type", 0)]) ); this->terms_.push_back(term); used_elements[m] += 1; @@ -127,7 +127,7 @@ void rel_qc_model::create_terms() { term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(i, count[lat.get_prop("type", i)])); + term.push_back( std::make_pair(i, count[lat.get_prop("type", i)])); this->terms_.push_back(term); } used_elements[m] += 1; diff --git a/dmrg/framework/dmrg/models/chem/su2u1/model.hpp b/dmrg/framework/dmrg/models/chem/su2u1/model.hpp index 234d0c4e6..eeb523f21 100644 --- a/dmrg/framework/dmrg/models/chem/su2u1/model.hpp +++ b/dmrg/framework/dmrg/models/chem/su2u1/model.hpp @@ -95,7 +95,7 @@ void qc_su2::create_terms() term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(0, ops.ident[lat.get_prop("type", 0)]) ); + term.push_back( std::make_pair(0, ops.ident[lat.get_prop("type", 0)]) ); this->terms_.push_back(term); used_elements[m] += 1; @@ -106,7 +106,7 @@ void qc_su2::create_terms() term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back( boost::make_tuple(i, ops.count[lat.get_prop("type", i)])); + term.push_back( std::make_pair(i, ops.count[lat.get_prop("type", i)])); this->terms_.push_back(term); used_elements[m] += 1; @@ -166,7 +166,7 @@ void qc_su2::create_terms() term_descriptor term; term.coeff = matrix_elements[m]; - term.push_back(boost::make_tuple(i, ops.docc[lat.get_prop("type", i)])); + term.push_back(std::make_pair(i, ops.docc[lat.get_prop("type", i)])); this->terms_.push_back(term); used_elements[m] += 1; diff --git a/dmrg/framework/dmrg/models/chem/su2u1/term_maker.h b/dmrg/framework/dmrg/models/chem/su2u1/term_maker.h index 26d164ca1..70b510aae 100644 --- a/dmrg/framework/dmrg/models/chem/su2u1/term_maker.h +++ b/dmrg/framework/dmrg/models/chem/su2u1/term_maker.h @@ -449,8 +449,8 @@ struct TermMakerSU2 { term_descriptor term; term.is_fermionic = sign; term.coeff = scale; - term.push_back(boost::make_tuple(i, op1[lat.get_prop("type", i)])); - term.push_back(boost::make_tuple(j, op2[lat.get_prop("type", j)])); + term.push_back(std::make_pair(i, op1[lat.get_prop("type", i)])); + term.push_back(std::make_pair(j, op2[lat.get_prop("type", j)])); return term; } @@ -466,9 +466,9 @@ struct TermMakerSU2 { if (j("type", start)]) ); + term.push_back( std::make_pair(start, op1_use[lat.get_prop("type", start)]) ); - term.push_back( boost::make_tuple(end, op2_use[lat.get_prop("type", end)]) ); + term.push_back( std::make_pair(end, op2_use[lat.get_prop("type", end)]) ); return term; } @@ -499,9 +499,9 @@ struct TermMakerSU2 { if (p2("type", pb)]) ); - term.push_back( boost::make_tuple(start, op1_use[lat.get_prop("type", start)]) ); - term.push_back( boost::make_tuple(end, op2_use[lat.get_prop("type", end)]) ); + term.push_back( std::make_pair(pb, boson_op_use[lat.get_prop("type", pb)]) ); + term.push_back( std::make_pair(start, op1_use[lat.get_prop("type", start)]) ); + term.push_back( std::make_pair(end, op2_use[lat.get_prop("type", end)]) ); //maquis::cout << " term " << pb << p1 << p2 << " " << boson_op_use[lat.get_prop("type", pb)] << "," << op1_use[lat.get_prop("type", start)] << "," << op2_use[lat.get_prop("type", end)] << std::endl; @@ -533,16 +533,16 @@ struct TermMakerSU2 { std::sort(sterm.begin(), sterm.end(), compare_tag); if (max_two_S == 2) { - term.push_back(make_tuple(get<0>(sterm[0]), get<1>(sterm[0]).fill_couple_up[lat.get_prop("type", get<0>(sterm[0]))])); - term.push_back(make_tuple(get<0>(sterm[1]), get<1>(sterm[1]).couple_up[lat.get_prop("type", get<0>(sterm[1]))])); - term.push_back(make_tuple(get<0>(sterm[2]), get<1>(sterm[2]).fill_couple_down[lat.get_prop("type", get<0>(sterm[2]))])); - term.push_back(make_tuple(get<0>(sterm[3]), get<1>(sterm[3]).couple_down[lat.get_prop("type", get<0>(sterm[3]))])); + term.push_back(std::make_pair(get<0>(sterm[0]), get<1>(sterm[0]).fill_couple_up[lat.get_prop("type", get<0>(sterm[0]))])); + term.push_back(std::make_pair(get<0>(sterm[1]), get<1>(sterm[1]).couple_up[lat.get_prop("type", get<0>(sterm[1]))])); + term.push_back(std::make_pair(get<0>(sterm[2]), get<1>(sterm[2]).fill_couple_down[lat.get_prop("type", get<0>(sterm[2]))])); + term.push_back(std::make_pair(get<0>(sterm[3]), get<1>(sterm[3]).couple_down[lat.get_prop("type", get<0>(sterm[3]))])); } else { - term.push_back(make_tuple(get<0>(sterm[0]), get<1>(sterm[0]).fill_couple_up[lat.get_prop("type", get<0>(sterm[0]))])); - term.push_back(make_tuple(get<0>(sterm[1]), get<1>(sterm[1]).couple_down[lat.get_prop("type", get<0>(sterm[1]))])); - term.push_back(make_tuple(get<0>(sterm[2]), get<1>(sterm[2]).fill_couple_up[lat.get_prop("type", get<0>(sterm[2]))])); - term.push_back(make_tuple(get<0>(sterm[3]), get<1>(sterm[3]).couple_down[lat.get_prop("type", get<0>(sterm[3]))])); + term.push_back(std::make_pair(get<0>(sterm[0]), get<1>(sterm[0]).fill_couple_up[lat.get_prop("type", get<0>(sterm[0]))])); + term.push_back(std::make_pair(get<0>(sterm[1]), get<1>(sterm[1]).couple_down[lat.get_prop("type", get<0>(sterm[1]))])); + term.push_back(std::make_pair(get<0>(sterm[2]), get<1>(sterm[2]).fill_couple_up[lat.get_prop("type", get<0>(sterm[2]))])); + term.push_back(std::make_pair(get<0>(sterm[3]), get<1>(sterm[3]).couple_down[lat.get_prop("type", get<0>(sterm[3]))])); } return term; @@ -585,7 +585,7 @@ class SpinSumSU2 { case 1: term_descriptor term; term.coeff = value_type(2.)*matrix_element; // 2 spin combinations are non-zero - term.push_back(boost::make_tuple(i, ops.docc.no_couple[lat.get_prop("type", i)])); + term.push_back(std::make_pair(i, ops.docc.no_couple[lat.get_prop("type", i)])); return std::vector(1, term); } diff --git a/dmrg/framework/dmrg/models/coded/models_2u1.hpp b/dmrg/framework/dmrg/models/coded/models_2u1.hpp deleted file mode 100644 index 001a7e87a..000000000 --- a/dmrg/framework/dmrg/models/coded/models_2u1.hpp +++ /dev/null @@ -1,322 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Bela Bauer - * Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef MODELS_CODED_2U1_H -#define MODELS_CODED_2U1_H - -#include - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/utils/BaseParameters.h" - -/* ****************** FERMI HUBBARD */ -template -class FermiHubbardTwoU1 : public model_impl -{ -public: - typedef model_impl base; - - typedef typename base::table_type table_type; - typedef typename base::table_ptr table_ptr; - typedef typename base::tag_type tag_type; - - typedef typename base::term_descriptor term_descriptor; - typedef typename base::terms_type terms_type; - typedef typename base::op_t op_t; - typedef typename base::measurements_type measurements_type; - - typedef typename Matrix::value_type value_type; - - FermiHubbardTwoU1(const Lattice& lat_, BaseParameters & parms_) - : lat(lat_) - , parms(parms_) - , tag_handler(new TagHandler()) - { - TwoU1::charge A(0), B(0), C(0), D(1); - B[0]=1; C[1]=1; - phys.insert(std::make_pair(A, 1)); - phys.insert(std::make_pair(B, 1)); - phys.insert(std::make_pair(C, 1)); - phys.insert(std::make_pair(D, 1)); - - op_t create_up_op, create_down_op, destroy_up_op, destroy_down_op, - count_up_op, count_down_op, doubly_occ_op, - fill_op, ident_op; - - ident_op.insert_block(Matrix(1, 1, 1), A, A); - ident_op.insert_block(Matrix(1, 1, 1), B, B); - ident_op.insert_block(Matrix(1, 1, 1), C, C); - ident_op.insert_block(Matrix(1, 1, 1), D, D); - - create_up_op.insert_block(Matrix(1, 1, 1), A, B); - create_up_op.insert_block(Matrix(1, 1, 1), C, D); - create_down_op.insert_block(Matrix(1, 1, 1), A, C); - create_down_op.insert_block(Matrix(1, 1, 1), B, D); - - destroy_up_op.insert_block(Matrix(1, 1, 1), B, A); - destroy_up_op.insert_block(Matrix(1, 1, 1), D, C); - destroy_down_op.insert_block(Matrix(1, 1, 1), C, A); - destroy_down_op.insert_block(Matrix(1, 1, 1), D, B); - - count_up_op.insert_block(Matrix(1, 1, 1), B, B); - count_up_op.insert_block(Matrix(1, 1, 1), D, D); - count_down_op.insert_block(Matrix(1, 1, 1), C, C); - count_down_op.insert_block(Matrix(1, 1, 1), D, D); - - doubly_occ_op.insert_block(Matrix(1, 1, 1), D, D); - - // TODO: use one sign operator only - fill_op.insert_block(Matrix(1, 1, 1), A, A); - fill_op.insert_block(Matrix(1, 1, -1), B, B); - fill_op.insert_block(Matrix(1, 1, -1), C, C); - fill_op.insert_block(Matrix(1, 1, 1), D, D); - - op_t tmp; - - gemm(fill_op, create_down_op, tmp); - create_down_op = tmp; - gemm(destroy_down_op, fill_op, tmp); - destroy_down_op = tmp; - - /**********************************************************************/ - /*** Create operator tag table ****************************************/ - /**********************************************************************/ - -#define REGISTER(op, kind) op = tag_handler->register_op(op ## _op, kind); - - REGISTER(ident, tag_detail::bosonic) - REGISTER(fill, tag_detail::bosonic) - REGISTER(create_up, tag_detail::fermionic) - REGISTER(create_down, tag_detail::fermionic) - REGISTER(destroy_up, tag_detail::fermionic) - REGISTER(destroy_down, tag_detail::fermionic) - REGISTER(count_up, tag_detail::bosonic) - REGISTER(count_down, tag_detail::bosonic) - REGISTER(doubly_occ, tag_detail::bosonic) - -#undef REGISTER - /**********************************************************************/ - - value_type U = parms["U"]; - std::pair ptag; - for (int p=0; pterms_.push_back(term); - } - - std::vector neighs = lat.forward(p); - for (std::vector::iterator hopto = neighs.begin(); - hopto != neighs.end(); ++hopto) - { - value_type ti = get_t(parms, - lat.get_prop("type", p, *hopto)); - { // t*cdag_up*c_up - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, create_up); // Note inverse notation because of notation in operator. - term.coeff *= ptag.second; - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(*hopto, destroy_up) ); - this->terms_.push_back(term); - } - { // t*c_up*cdag_up - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, destroy_up); // Note inverse notation because of notation in operator. - term.coeff *= -ptag.second; // Note minus because of anti-commutation - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(*hopto, create_up) ); - this->terms_.push_back(term); - } - { // t*cdag_down*c_down - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, create_down); // Note inverse notation because of notation in operator. - term.coeff *= ptag.second; - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(*hopto, destroy_down) ); - this->terms_.push_back(term); - } - { // t*c_down*cdag_down - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, destroy_down); // Note inverse notation because of notation in operator. - term.coeff *= -ptag.second; // Note minus because of anti-commutation - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(*hopto, create_down) ); - this->terms_.push_back(term); - } - } - } - } - - void update(BaseParameters const& p) - { - // TODO: update this->terms_ with the new parameters - throw std::runtime_error("update() not yet implemented for this model."); - return; - } - - Index const & phys_dim(size_t type) const - { - return phys; - } - - measurements_type measurements () const - { - typedef std::vector op_vec; - typedef std::vector > bond_element; - - measurements_type meas; - - if (parms["MEASURE[Density]"]) { - meas.push_back( new measurements::average("Density up", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_up))) ); - } - if (parms["MEASURE[Density]"]) { - meas.push_back( new measurements::average("Density down", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_down))) ); - } - - if (parms["MEASURE[Local density]"]) { - meas.push_back( new measurements::local("Local density up", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_up))) ); - } - if (parms["MEASURE[Local density]"]) { - meas.push_back( new measurements::local("Local density down", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_down))) ); - } - - if (parms["MEASURE[Onebody density matrix]"]) { - bond_element ops; - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(create_up)), true) ); - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(destroy_up)), true) ); - meas.push_back( new measurements::correlations("Onebody density matrix up", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - ops, false, false) ); - } - if (parms["MEASURE[Onebody density matrix]"]) { - bond_element ops; - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(create_down)), true) ); - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(destroy_down)), true) ); - meas.push_back( new measurements::correlations("Onebody density matrix down", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - ops, false, false) ); - } - - return meas; - } - - tag_type identity_matrix_tag(size_t type) const - { - return ident; - } - tag_type filling_matrix_tag(size_t type) const - { - return fill; - } - typename TwoU1::charge total_quantum_numbers(BaseParameters & parms) const - { - typename TwoU1::charge ret(0); - ret[0] = static_cast(parms["u1_total_charge1"]); - ret[1] = static_cast(parms["u1_total_charge2"]); - return ret; - } - - tag_type get_operator_tag(std::string const & name, size_t type) const - { - if (name == "create_up") - return create_up; - else if (name == "create_down") - return create_down; - else if (name == "destroy_up") - return destroy_up; - else if (name == "destroy_down") - return destroy_down; - else if (name == "count_up") - return count_up; - else if (name == "count_down") - return count_down; - else if (name == "doubly_occ") - return doubly_occ; - else - throw std::runtime_error("Operator not valid for this model."); - return 0; - } - - table_ptr operators_table() const - { - return tag_handler; - } - -private: - Index phys; - - Lattice const & lat; - BaseParameters & parms; - - std::shared_ptr > tag_handler; - tag_type create_up, create_down, destroy_up, destroy_down, - count_up, count_down, doubly_occ, - ident, fill; - - - double get_t (BaseParameters & parms, int i) const - { - std::ostringstream key; - key << "t" << (i+1); - return (parms.is_set(key.str())) ? parms[key.str()] : parms["t"]; - } -}; - -#endif diff --git a/dmrg/framework/dmrg/models/coded/models_su2.hpp b/dmrg/framework/dmrg/models/coded/models_su2.hpp deleted file mode 100644 index 05e1f088d..000000000 --- a/dmrg/framework/dmrg/models/coded/models_su2.hpp +++ /dev/null @@ -1,328 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Bela Bauer - * Michele Dolfi - * 2014-2014 by Sebastian Keller - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef MODELS_CODED_SU2_H -#define MODELS_CODED_SU2_H - -#include - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/utils/BaseParameters.h" - -/* ****************** FERMI HUBBARD */ -template -class FermiHubbardSU2 : public model_impl -{ -public: - typedef model_impl base; - - typedef typename base::table_type table_type; - typedef typename base::table_ptr table_ptr; - typedef typename base::tag_type tag_type; - - typedef typename base::term_descriptor term_descriptor; - typedef typename base::terms_type terms_type; - typedef typename base::op_t op_t; - typedef typename base::measurements_type measurements_type; - - typedef typename Matrix::value_type value_type; - typedef Lattice::pos_t pos_t; - - FermiHubbardSU2(const Lattice& lat_, BaseParameters & parms_) - : lat(lat_) - , parms(parms_) - , tag_handler(new TagHandler()) - { - SU2U1::charge A(0), B(0), C(0), D(0); - A[0] = 2; // 20 - B[0] = 1; B[1] = 1; // 11 - C[0] = 1; C[1] = -1; // 1-1 - // D = 00 - - SpinDescriptor::type> one_half_up(1,0,1); - SpinDescriptor::type> one_half_down(1,1,0); - - phys.insert(std::make_pair(A,1)); - phys.insert(std::make_pair(B,1)); - phys.insert(std::make_pair(C,1)); - phys.insert(std::make_pair(D,1)); - - op_t identity_op; - identity_op.insert_block(Matrix(1,1,1), A, A); - identity_op.insert_block(Matrix(1,1,1), B, B); - identity_op.insert_block(Matrix(1,1,1), C, C); - identity_op.insert_block(Matrix(1,1,1), D, D); - - op_t fill_op; - fill_op.insert_block(Matrix(1,1,1), A, A); - fill_op.insert_block(Matrix(1,1,1), D, D); - fill_op.insert_block(Matrix(1,1,-1), B, B); - fill_op.insert_block(Matrix(1,1,-1), C, C); - fill_op.insert_block(Matrix(1,1,-1), B, C); - fill_op.insert_block(Matrix(1,1,-1), C, B); - - /*************************************************************/ - - op_t create_fill_op; - create_fill_op.spin() = one_half_up; - create_fill_op.insert_block(Matrix(1,1,sqrt(2.)), B, A); - create_fill_op.insert_block(Matrix(1,1,sqrt(2.)), C, A); - create_fill_op.insert_block(Matrix(1,1,1), D, B); - create_fill_op.insert_block(Matrix(1,1,1), D, C); - - op_t destroy_op; - destroy_op.spin() = one_half_down; - destroy_op.insert_block(Matrix(1,1,1), A, B); - destroy_op.insert_block(Matrix(1,1,1), A, C); - destroy_op.insert_block(Matrix(1,1,sqrt(2.)), B, D); - destroy_op.insert_block(Matrix(1,1,sqrt(2.)), C, D); - - op_t destroy_fill_op; - destroy_fill_op.spin() = one_half_up; - destroy_fill_op.insert_block(Matrix(1,1,1), A, B); - destroy_fill_op.insert_block(Matrix(1,1,1), A, C); - destroy_fill_op.insert_block(Matrix(1,1,-sqrt(2.)), B, D); - destroy_fill_op.insert_block(Matrix(1,1,-sqrt(2.)), C, D); - - op_t create_op; - create_op.spin() = one_half_down; - create_op.insert_block(Matrix(1,1,sqrt(2.)), B, A); - create_op.insert_block(Matrix(1,1,sqrt(2.)), C, A); - create_op.insert_block(Matrix(1,1,-1), D, B); - create_op.insert_block(Matrix(1,1,-1), D, C); - - /*************************************************************/ - - op_t count_op; - count_op.insert_block(Matrix(1,1,2), A, A); - count_op.insert_block(Matrix(1,1,1), B, B); - count_op.insert_block(Matrix(1,1,1), C, C); - - op_t doubly_occ_op; - doubly_occ_op.insert_block(Matrix(1,1,1), A, A); - - /**********************************************************************/ - /*** Create operator tag table ****************************************/ - /**********************************************************************/ - - #define REGISTER(op, kind) op = tag_handler->register_op(op ## _op, kind); - - REGISTER(identity, tag_detail::bosonic) - REGISTER(fill, tag_detail::bosonic) - REGISTER(create_fill, tag_detail::fermionic) - REGISTER(create, tag_detail::fermionic) - REGISTER(destroy, tag_detail::fermionic) - REGISTER(destroy_fill, tag_detail::fermionic) - REGISTER(count, tag_detail::bosonic) - REGISTER(doubly_occ, tag_detail::bosonic) - - #undef REGISTER - /**********************************************************************/ - - struct TM { - static term_descriptor positional_two_term(bool sign, tag_type full_ident, value_type scale, pos_t i, pos_t j, - tag_type op1, tag_type op1_fill, tag_type op2, tag_type op2_fill) - { - term_descriptor term; - term.is_fermionic = sign; - term.coeff = scale; - - tag_type op1_use = (i ptag; - for (int p=0; pterms_.push_back(term); - } - - std::vector neighs = lat.forward(p); - for (std::vector::iterator hopto = neighs.begin(); - hopto != neighs.end(); ++hopto) - { - value_type ti = get_t(parms, - lat.get_prop("type", p, *hopto)); - - // The sqrt(2.) balances the magnitudes of Clebsch coeffs C^{1/2 1/2 0}_{mrm'} which apply at the second spin-1/2 operator - this->terms_.push_back(TM::positional_two_term( - true, identity, value_type(std::sqrt(2.)) * ti, *hopto, p, create, create_fill, destroy, destroy_fill - )); - this->terms_.push_back(TM::positional_two_term( - true, identity, value_type(std::sqrt(2.)) * ti, p, *hopto, create, create_fill, destroy, destroy_fill - )); - } - } - } - - void update(BaseParameters const& p) - { - // TODO: update this->terms_ with the new parameters - throw std::runtime_error("update() not yet implemented for this model."); - return; - } - - Index const & phys_dim(size_t type) const - { - return phys; - } - - measurements_type measurements () const - { - typedef std::vector op_vec; - typedef std::vector > bond_element; - - measurements_type meas; - - /* - if (parms["ENABLE_MEASURE[Density]"]) { - meas.push_back( new measurements::average("Density up", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_up))) ); - } - if (parms["ENABLE_MEASURE[Density]"]) { - meas.push_back( new measurements::average("Density down", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_down))) ); - } - - if (parms["ENABLE_MEASURE[Local density]"]) { - meas.push_back( new measurements::local("Local density up", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_up))) ); - } - if (parms["ENABLE_MEASURE[Local density]"]) { - meas.push_back( new measurements::local("Local density down", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - op_vec(1,tag_handler->get_op(count_down))) ); - } - - if (parms["ENABLE_MEASURE[Onebody density matrix]"]) { - bond_element ops; - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(create_up)), true) ); - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(destroy_up)), true) ); - meas.push_back( new measurements::correlations("Onebody density matrix up", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - ops, false, false) ); - } - if (parms["ENABLE_MEASURE[Onebody density matrix]"]) { - bond_element ops; - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(create_down)), true) ); - ops.push_back( std::make_pair(op_vec(1,tag_handler->get_op(destroy_down)), true) ); - meas.push_back( new measurements::correlations("Onebody density matrix down", lat, - op_vec(1,this->identity_matrix(0)), - op_vec(1,this->filling_matrix(0)), - ops, false, false) ); - } - */ - - return meas; - } - - tag_type identity_matrix_tag(size_t type) const - { - return identity; - } - tag_type filling_matrix_tag(size_t type) const - { - return fill; - } - typename SU2U1::charge total_quantum_numbers(BaseParameters & parms) const - { - typename SU2U1::charge ret(0); - ret[0] = static_cast(parms["u1_total_charge1"]); - ret[1] = static_cast(parms["su2_total_charge"]); - return ret; - } - - tag_type get_operator_tag(std::string const & name, size_t type) const - { - if (name == "create") - return create; - else if (name == "create_fill") - return create_fill; - else if (name == "destroy") - return destroy; - else if (name == "destroy_fill") - return destroy_fill; - else if (name == "count") - return count; - else if (name == "doubly_occ") - return doubly_occ; - else if (name == "ident_full") - return identity; - else - throw std::runtime_error("Operator not valid for this model."); - return 0; - } - - table_ptr operators_table() const - { - return tag_handler; - } - -private: - Index phys; - - Lattice const & lat; - BaseParameters & parms; - - std::shared_ptr > tag_handler; - tag_type create, create_fill, destroy, destroy_fill, - count, doubly_occ, - identity, fill; - - - double get_t (BaseParameters & parms, int i) const - { - std::ostringstream key; - key << "t" << (i+1); - return (parms.is_set(key.str())) ? parms[key.str()] : parms["t"]; - } -}; - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/factory.h b/dmrg/framework/dmrg/models/continuum/factory.h deleted file mode 100644 index f95a8fd5e..000000000 --- a/dmrg/framework/dmrg/models/continuum/factory.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef MAQUIS_DMRG_MODELS_CONT_FACTORY_H -#define MAQUIS_DMRG_MODELS_CONT_FACTORY_H - -#include "dmrg/utils/BaseParameters.h" -#include "dmrg/models/lattice.h" -#include "dmrg/models/model.h" - -template -struct cont_model_factory { - static std::shared_ptr > - parse(Lattice const &, BaseParameters &) - { - typedef std::shared_ptr > impl_ptr; - throw std::runtime_error("Don't know any continuum model with this symmetry group!"); - return impl_ptr(); - - } -}; - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/factory_2u1.ipp b/dmrg/framework/dmrg/models/continuum/factory_2u1.ipp deleted file mode 100644 index 59e15d4bf..000000000 --- a/dmrg/framework/dmrg/models/continuum/factory_2u1.ipp +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#include "dmrg/models/continuum/models_2u1.hpp" -//#include "dmrg/models/continuum/super_models_2u1.hpp" -#include "dmrg/models/continuum/factory.h" - -template -struct cont_model_factory { - static std::shared_ptr > parse - (Lattice const & lattice, BaseParameters & model) - { - typedef std::shared_ptr > impl_ptr; - std::string model_str = model.is_set("model") ? "model" : "MODEL"; - if (model[model_str] == std::string("fermi_optical_lattice")) - return impl_ptr( new FermiOpticalLattice(lattice, model) ); -// else if (model[model_str] == std::string("optical_lattice_cons_dm")) -// return impl_ptr( new DMOpticalLatticeTwoU1(lattice, model) ); -// else { - throw std::runtime_error("Don't know this model!"); - return impl_ptr(); -// } - } -}; diff --git a/dmrg/framework/dmrg/models/continuum/factory_lattice.hpp b/dmrg/framework/dmrg/models/continuum/factory_lattice.hpp deleted file mode 100644 index 4efd5f29c..000000000 --- a/dmrg/framework/dmrg/models/continuum/factory_lattice.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef MAQUIS_DMRG_MODELS_CONTINUUM_FACTORY_LATTICE_H -#define MAQUIS_DMRG_MODELS_CONTINUUM_FACTORY_LATTICE_H - -#include "dmrg/models/continuum/lattice.hpp" - -inline std::shared_ptr cont_lattice_factory (BaseParameters & parms) -{ - typedef std::shared_ptr impl_ptr; - std::string lat_str = parms.is_set("lattice") ? "lattice" : "LATTICE"; - if (parms[lat_str] == std::string("continuous_chain") - || parms[lat_str] == std::string("continuous_left_chain") - || parms[lat_str] == std::string("continuous_center_chain")) - return impl_ptr(new ContChain(parms, false)); - else if (parms[lat_str] == std::string("periodic_continuous_chain")) - return impl_ptr(new ContChain(parms, true)); - else { - throw std::runtime_error("Don't know this lattice!"); - } -} - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/factory_none.ipp b/dmrg/framework/dmrg/models/continuum/factory_none.ipp deleted file mode 100644 index 72010d667..000000000 --- a/dmrg/framework/dmrg/models/continuum/factory_none.ipp +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -//#include "dmrg/models/continuum/models_none.hpp" -#include "dmrg/models/continuum/factory.h" - - -template -struct cont_model_factory { - static std::shared_ptr > parse - (Lattice const& lattice, BaseParameters & parms) - { - typedef std::shared_ptr > impl_ptr; -// if (parms["MODEL"] == std::string("optical_lattice")) -// return impl_ptr( new OpticalLatticeNull(lattice, model) ); - - throw std::runtime_error("No coded models using the NU1 SymmGroup"); - return impl_ptr(); - } -}; - diff --git a/dmrg/framework/dmrg/models/continuum/factory_u1.ipp b/dmrg/framework/dmrg/models/continuum/factory_u1.ipp deleted file mode 100644 index 6978b8179..000000000 --- a/dmrg/framework/dmrg/models/continuum/factory_u1.ipp +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#include "dmrg/models/continuum/models_u1.hpp" -//#include "dmrg/models/continuum/super_models_u1.hpp" -#include "dmrg/models/continuum/factory.h" - - -template -struct cont_model_factory { - static std::shared_ptr > parse - (Lattice const& lattice, BaseParameters & parms) - { - typedef std::shared_ptr > impl_ptr; - if (parms["MODEL"] == std::string("optical_lattice") || parms["MODEL"] == std::string("optical lattice")) - return impl_ptr( new OpticalLattice(lattice, parms) ); -// else if (parms["MODEL"] == std::string("optical_lattice_dm")) -// return impl_ptr( new DMOpticalLattice(lattice, parms) ); - else { - throw std::runtime_error("Don't know this model!"); - return impl_ptr(); - } - } -}; diff --git a/dmrg/framework/dmrg/models/continuum/lattice.hpp b/dmrg/framework/dmrg/models/continuum/lattice.hpp deleted file mode 100644 index 86a47b46e..000000000 --- a/dmrg/framework/dmrg/models/continuum/lattice.hpp +++ /dev/null @@ -1,417 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef CONTINUOUS_LATTICE_H -#define CONTINUOUS_LATTICE_H - -#include "dmrg/models/lattice.h" - -#include -#include - -#include "dmrg/utils/BaseParameters.h" - -class ContChain : public lattice_impl -{ -public: - typedef lattice_impl::pos_t pos_t; - - ContChain (BaseParameters & parms, bool pbc_=false) - : L(parms["L"]) - , N(parms["Ndiscr"]) - , a(parms["a"]) - , pbc(pbc_) - {} - - std::vector forward(pos_t i) const - { - std::vector ret; - if (i < L*N-1) - ret.push_back(i+1); - if (pbc && i == L*N-1) - ret.push_back(0); - return ret; - } - std::vector all(pos_t i) const - { - std::vector ret; - if (i < L*N-1) - ret.push_back(i+1); - if (i > 0) - ret.push_back(i-1); - if (pbc && i == L*N-1) - ret.push_back(0); - if (pbc && i == 0) - ret.push_back(L*N-1); - return ret; - } - - boost::any get_prop_(std::string const & property, std::vector const & pos) const - { - if (property == "label" && pos.size() == 1) - return boost::any( site_label(pos[0]) ); - else if (property == "label" && pos.size() == 2) - return boost::any( bond_label(pos[0], pos[1]) ); - else if (property == "type" && pos.size() == 1) - return boost::any( pos[0]%N ); - else if (property == "type" && pos.size() == 2) - return boost::any( 0 ); - else if (property == "x" && pos.size() == 1) - return boost::any( a/N/2. + a/N * pos[0] ); - else if (property == "dx" && pos.size() == 1) - return boost::any( a/N ); - else if (property == "dx" && pos.size() == 2) - return boost::any( a/N * (pos[1]-pos[0]) ); - else if (property == "at_open_boundary" && pos.size() == 1) - return boost::any( (!pbc) && (pos[0]==0 || pos[0]==L*N-1) ); - else if (property == "at_open_left_boundary" && pos.size() == 1) - return boost::any( (!pbc) && pos[0]==0 ); - else if (property == "at_open_right_boundary" && pos.size() == 1) - return boost::any( (!pbc) && pos[0]==L*N-1 ); - else if (property == "wraps_pbc" && pos.size() == 2) - return boost::any( (pos[0] < pos[1]) ); - else { - std::ostringstream ss; - ss << "No property '" << property << "' with " << pos.size() << " points implemented."; - throw std::runtime_error(ss.str()); - return boost::any(); - } - } - - pos_t size() const - { - return L*N; - } - - int maximum_vertex_type() const - { - return N-1; - } - -private: - - std::string site_label (int i) const - { - return "( " + boost::lexical_cast(a/N/2. + a/N * i) + " )"; - } - - std::string bond_label (int i, int j) const - { - return ( "( " + boost::lexical_cast(a/N/2. + a/N * i) + " )" - + " -- " - + "( " + boost::lexical_cast(a/N/2. + a/N * j) + " )"); - } - -private: - int N, L; - double a; - bool pbc; - -}; - -class MixedContChain : public lattice_impl -{ -public: - typedef lattice_impl::pos_t pos_t; - - MixedContChain (BaseParameters & parms1, int L1_, BaseParameters & parms2, int L2_, bool pbc_=false) - : L1(L1_) - , L2(L2_) - , Lphys(parms1["L"]) - , N1(parms1["Ndiscr"]) - , a1(parms1["a"]) - , N2(parms2["Ndiscr"]) - , a2(parms2["a"]) - , pbc(pbc_) - { - assert( parms1["L"] == parms1["L"] ); - if (pbc) - throw std::runtime_error("Periodic boundary conditions are not implemented for the MixedChain."); - } - - std::vector forward(pos_t i) const - { - std::vector ret; - if (i < L1+L2-1) - ret.push_back(i+1); - if (pbc && i == L1+L2-1) - ret.push_back(0); - return ret; - } - std::vector all(pos_t i) const - { - std::vector ret; - if (i < L1+L2-1) - ret.push_back(i+1); - if (i > 0) - ret.push_back(i-1); - if (pbc && i == L1+L2-1) - ret.push_back(0); - if (pbc && i == 0) - ret.push_back(L1+L2-1); - return ret; - } - - boost::any get_prop_(std::string const & property, std::vector const & pos) const - { - if (property == "label" && pos.size() == 1) - return boost::any( site_label(pos[0]) ); - else if (property == "label" && pos.size() == 2) - return boost::any( bond_label(pos[0], pos[1]) ); - else if (property == "type" && pos.size() == 1) - return boost::any( 0 ); - else if (property == "type" && pos.size() == 2) - return boost::any( 0 ); - else if (property == "x" && pos.size() == 1) - return boost::any( get_x(pos[0]) ); - else if (property == "dx" && pos.size() == 1) - return boost::any( get_dx(pos[0]) ); - else if (property == "dx" && pos.size() == 2) - return boost::any( get_dx(pos[0], pos[1]) ); - else if (property == "at_open_boundary" && pos.size() == 1) - return boost::any( (!pbc) && (pos[0]==0 || pos[0]==L1+L2-1) ); - else if (property == "at_open_left_boundary" && pos.size() == 1) - return boost::any( (!pbc) && pos[0]==0 ); - else if (property == "at_open_right_boundary" && pos.size() == 1) - return boost::any( (!pbc) && pos[0]==L1+L2-1 ); - else if (property == "wraps_pbc" && pos.size() == 2) - return boost::any( (pos[0] < pos[1]) ); - else { - std::ostringstream ss; - ss << "No property '" << property << "' with " << pos.size() << " points implemented."; - throw std::runtime_error(ss.str()); - return boost::any(); - } - } - - pos_t size() const - { - return L1+L2; - } - - int maximum_vertex_type() const - { - return 0; - } - -private: - - double get_x (int i) const - { - int i1, i2; - if (i < L1) { - i1 = i; - i2 = 0; - } else { - i1 = L1; - i2 = i - L1; - } - - return a1/N1 * i1 + a2/N2 * i2; - } - - double get_dx (int i, int j) const - { - double dx; - if (std::max(i, j) <= L1) - dx = a1/N1 * (j-i); - else - dx = a2/N2 * (j-i); - return dx; - } - double get_dx (int i) const - { - return (i( get_x(i) ) + " )"; - } - - std::string bond_label (int i, int j) const - { - return ( "( " + boost::lexical_cast( get_x(i) ) + " )" - + " -- " - + "( " + boost::lexical_cast( get_x(j) ) + " )"); - } - -private: - int N1, N2, L1, L2; - double a1, a2, Lphys; - bool pbc; - -}; - - -class MixedContChain_c : public lattice_impl -{ -public: - typedef lattice_impl::pos_t pos_t; - - MixedContChain_c (BaseParameters & parms1, int L1_, BaseParameters & parms2, int L2_, bool pbc_=false) - : L1(L1_) - , L2(L2_) - , Lphys(parms1["L"]) - , N1(parms1["Ndiscr"]) - , a1(parms1["a"]) - , N2(parms2["Ndiscr"]) - , a2(parms2["a"]) - , pbc(pbc_) - { - assert( parms1["L"] == parms1["L"] ); - if (pbc) - throw std::runtime_error("Periodic boundary conditions are not implemented for the MixedChain."); - } - - std::vector forward(pos_t i) const - { - std::vector ret; - if (i < L1+L2-1) - ret.push_back(i+1); - if (pbc && i == L1+L2-1) - ret.push_back(0); - return ret; - } - std::vector all(pos_t i) const - { - std::vector ret; - if (i < L1+L2-1) - ret.push_back(i+1); - if (i > 0) - ret.push_back(i-1); - if (pbc && i == L1+L2-1) - ret.push_back(0); - if (pbc && i == 0) - ret.push_back(L1+L2-1); - return ret; - } - - boost::any get_prop_(std::string const & property, std::vector const & pos) const - { - if (property == "label" && pos.size() == 1) - return boost::any( site_label(pos[0]) ); - else if (property == "label" && pos.size() == 2) - return boost::any( bond_label(pos[0], pos[1]) ); - else if (property == "type" && pos.size() == 1) - return boost::any( 0 ); - else if (property == "type" && pos.size() == 2) - return boost::any( 0 ); - else if (property == "x" && pos.size() == 1) - return boost::any( get_x(pos[0]) ); - else if (property == "dx" && pos.size() == 1) - return boost::any( get_dx(pos[0]) ); - else if (property == "dx" && pos.size() == 2) - return boost::any( get_dx(pos[0], pos[1]) ); - else if (property == "at_open_boundary" && pos.size() == 1) - return boost::any( (!pbc) && (pos[0]==0 || pos[0]==L1+L2-1) ); - else if (property == "at_open_left_boundary" && pos.size() == 1) - return boost::any( (!pbc) && pos[0]==0 ); - else if (property == "at_open_right_boundary" && pos.size() == 1) - return boost::any( (!pbc) && pos[0]==L1+L2-1 ); - else if (property == "wraps_pbc" && pos.size() == 2) - return boost::any( (pos[0] < pos[1]) ); - else { - std::ostringstream ss; - ss << "No property '" << property << "' with " << pos.size() << " points implemented."; - throw std::runtime_error(ss.str()); - return boost::any(); - } - } - - pos_t size() const - { - return L1+L2; - } - - int maximum_vertex_type() const - { - return 0; - } - -private: - - double get_x (int i) const - { - int i1, i2; - double middle = 0; - double left = (L1 > 0) ? a1/N1/2. : a2/N2/2.; - if (L1 == 0) { - i1 = 0; - i2 = i; - middle = 0.; - } else if (i < L1) { - i1 = i; - i2 = 0; - middle = 0.; - } else { - i1 = L1-1; - i2 = i - L1; - middle = 3./2. * std::min(a1/N1, a2/N2); - } - - return left + a1/N1 * i1 + middle + a2/N2 * i2; - } - double get_dx (int i) const - { - return (i= L1) - return a2/N2 * (j-i); - else - return (j-i)/std::abs(j-i) * ( a1/N1 * (L1-1 - std::min(i,j)) - + 3./2. * std::min(a1/N1, a2/N2) - + a2/N2 * (std::max(i,j) - L1) ); - } - - std::string site_label (int i) const - { - return "( " + boost::lexical_cast( get_x(i) ) + " )"; - } - - std::string bond_label (int i, int j) const - { - return ( "( " + boost::lexical_cast( get_x(i) ) + " )" - + " -- " - + "( " + boost::lexical_cast( get_x(j) ) + " )"); - } - -private: - int N1, N2, L1, L2; - double a1, a2, Lphys; - bool pbc; - -}; - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/models_2u1.hpp b/dmrg/framework/dmrg/models/continuum/models_2u1.hpp deleted file mode 100644 index ca4d1bc74..000000000 --- a/dmrg/framework/dmrg/models/continuum/models_2u1.hpp +++ /dev/null @@ -1,373 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Bela Bauer - * Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef DMRG_CONTINUOUS_MODELS_2U1_H -#define DMRG_CONTINUOUS_MODELS_2U1_H - -#include - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/utils/BaseParameters.h" - -/* ****************** FERMIONIC OPTICAL LATTICE (with symmetry) */ -template -class FermiOpticalLattice : public model_impl -{ -public: - typedef model_impl base; - - typedef typename base::table_type table_type; - typedef typename base::table_ptr table_ptr; - typedef typename base::tag_type tag_type; - - typedef typename base::term_descriptor term_descriptor; - typedef typename base::terms_type terms_type; - typedef typename base::op_t op_t; - typedef typename base::measurements_type measurements_type; - - typedef typename Matrix::value_type value_type; - - FermiOpticalLattice(const Lattice& lat_, BaseParameters & parms_) - : lat(lat_) - , parms(parms_) - , tag_handler(new TagHandler()) - { - TwoU1::charge A(0), B(0), C(0), D(1); - B[0]=1; C[1]=1; - phys.insert(std::make_pair(A, 1)); - phys.insert(std::make_pair(B, 1)); - phys.insert(std::make_pair(C, 1)); - phys.insert(std::make_pair(D, 1)); - - op_t create_up_op, create_down_op, destroy_up_op, destroy_down_op, - count_up_op, count_down_op, count_op, doubly_occ_op, - fill_op, ident_op; - - ident_op.insert_block(Matrix(1, 1, 1), A, A); - ident_op.insert_block(Matrix(1, 1, 1), B, B); - ident_op.insert_block(Matrix(1, 1, 1), C, C); - ident_op.insert_block(Matrix(1, 1, 1), D, D); - - create_up_op.insert_block(Matrix(1, 1, 1), A, B); - create_up_op.insert_block(Matrix(1, 1, 1), C, D); - create_down_op.insert_block(Matrix(1, 1, 1), A, C); - create_down_op.insert_block(Matrix(1, 1, 1), B, D); - - destroy_up_op.insert_block(Matrix(1, 1, 1), B, A); - destroy_up_op.insert_block(Matrix(1, 1, 1), D, C); - destroy_down_op.insert_block(Matrix(1, 1, 1), C, A); - destroy_down_op.insert_block(Matrix(1, 1, 1), D, B); - - count_up_op.insert_block(Matrix(1, 1, 1), B, B); - count_up_op.insert_block(Matrix(1, 1, 1), D, D); - count_down_op.insert_block(Matrix(1, 1, 1), C, C); - count_down_op.insert_block(Matrix(1, 1, 1), D, D); - count_op.insert_block(Matrix(1, 1, 1), B, B); - count_op.insert_block(Matrix(1, 1, 1), C, C); - count_op.insert_block(Matrix(1, 1, 2), D, D); - - doubly_occ_op.insert_block(Matrix(1, 1, 1), D, D); - - fill_op.insert_block(Matrix(1, 1, 1), A, A); - fill_op.insert_block(Matrix(1, 1, -1), B, B); - fill_op.insert_block(Matrix(1, 1, -1), C, C); - fill_op.insert_block(Matrix(1, 1, 1), D, D); - - op_t tmp; - - gemm(fill_op, create_down_op, tmp); - create_down_op = tmp; - gemm(destroy_down_op, fill_op, tmp); - destroy_down_op = tmp; - - /**********************************************************************/ - /*** Create operator tag table ****************************************/ - /**********************************************************************/ - -#define REGISTER(op, kind) op = tag_handler->register_op(op ## _op, kind); - - REGISTER(ident, tag_detail::bosonic) - REGISTER(fill, tag_detail::bosonic) - REGISTER(create_up, tag_detail::fermionic) - REGISTER(create_down, tag_detail::fermionic) - REGISTER(destroy_up, tag_detail::fermionic) - REGISTER(destroy_down, tag_detail::fermionic) - REGISTER(count_up, tag_detail::bosonic) - REGISTER(count_down, tag_detail::bosonic) - REGISTER(count, tag_detail::bosonic) - REGISTER(doubly_occ, tag_detail::bosonic) - -#undef REGISTER - /**********************************************************************/ - - generate_terms(); - } - - void update(BaseParameters const& p) - { - parms << p; - generate_terms(); - return; - } - - Index const & phys_dim(size_t type) const - { - return phys; - } - - measurements_type measurements () const - { - typedef std::vector op_vec; - typedef std::vector > bond_element; - - std::size_t ntypes = lat.maximum_vertex_type()+1; - - measurements_type meas; - - if (parms["MEASURE[Density]"]) { - meas.push_back( new measurements::average("Density up", lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - op_vec(ntypes,tag_handler->get_op(count_up))) ); - } - if (parms["MEASURE[Density]"]) { - meas.push_back( new measurements::average("Density down", lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - op_vec(ntypes,tag_handler->get_op(count_down))) ); - } - - if (parms["MEASURE[Local density]"]) { - meas.push_back( new measurements::local("Local density up", lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - op_vec(ntypes,tag_handler->get_op(count_up))) ); - } - if (parms["MEASURE[Local density]"]) { - meas.push_back( new measurements::local("Local density down", lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - op_vec(ntypes,tag_handler->get_op(count_down))) ); - } - - if (parms["MEASURE[Onebody density matrix]"]) { - bond_element ops; - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(create_up)), true) ); - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(destroy_up)), true) ); - meas.push_back( new measurements::correlations("Onebody density matrix up", lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - ops, false, false) ); - } - if (parms["MEASURE[Onebody density matrix]"]) { - bond_element ops; - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(create_down)), true) ); - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(destroy_down)), true) ); - meas.push_back( new measurements::correlations("Onebody density matrix down", lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - ops, false, false) ); - } - - return meas; - } - - tag_type identity_matrix_tag(size_t type) const - { - return ident; - } - tag_type filling_matrix_tag(size_t type) const - { - return fill; - } - typename TwoU1::charge total_quantum_numbers(BaseParameters & parms) const - { - typename TwoU1::charge ret(0); - ret[0] = static_cast(parms["Nup_total"]); - ret[1] = static_cast(parms["Ndown_total"]); - return ret; - } - - tag_type get_operator_tag(std::string const & name, size_t type) const - { - if (name == "create_up") - return create_up; - else if (name == "create_down") - return create_down; - else if (name == "destroy_up") - return destroy_up; - else if (name == "destroy_down") - return destroy_down; - else if (name == "count_up") - return count_up; - else if (name == "count_down") - return count_down; - else if (name == "doubly_occ") - return doubly_occ; - else - throw std::runtime_error("Operator not valid for this model."); - return 0; - } - - table_ptr operators_table() const - { - return tag_handler; - } - -private: - void generate_terms() { - this->terms_.clear(); - - value_type k = parms["k"]; - value_type c = parms["c"]; - value_type V0 = parms["V0"]; - value_type V1 = parms["V1"]; - value_type V2 = parms["V2"]; - value_type w = parms["omega"]; - value_type shift = parms["shift"]; - - typedef typename maquis::traits::real_type::type real_type; - - std::pair ptag; - for (int p=0; p neighs = lat.forward(p); - - real_type x = lat.get_prop("x", p); - - value_type exp_potential = V0*std::pow( std::cos(k*x), 2 ); - exp_potential += ( -V1*std::pow( std::cos(k*x), 2 ) - +V2*std::pow( std::cos(real_type(2.)*k*x), 2 ) ); - exp_potential += w*w/real_type(2.) * std::pow(x - shift, 2 ); - - // MD: simplified version with uniform spacing - real_type dx1 = lat.get_prop("dx", p, hopto); - real_type dx2 = -dx1; - real_type dx0 = lat.get_prop("dx", p); - - // Psi''(x) = coeff1 * Psi(x+dx1) + coeff0 * Psi(x) + coeff2 * Psi(x+dx2) - real_type coeff1 = real_type(2.) / (dx1*dx1 - dx1*dx2); - real_type coeff2 = real_type(2.) / (dx2*dx2 - dx1*dx2); - real_type coeff0 = -(coeff1 + coeff2); - - - value_type U = c / dx0; - value_type mu = exp_potential - real_type(parms["mu"]); - mu += -coeff0 * parms["h"]; - - value_type ti = coeff1 * parms["h"]; - - -#ifndef NDEBUG - maquis::cout << "U = " << U << ", mu = " << mu << ", t = " << ti << std::endl; -#endif - - - { // U term - term_descriptor term; - term.coeff = U; - term.push_back( boost::make_tuple(p, doubly_occ) ); - this->terms_.push_back(term); - } - - { // mu term - term_descriptor term; - term.coeff = mu; - term.push_back( boost::make_tuple(p, count) ); - this->terms_.push_back(term); - } - - if (hopto < lat.size()) { - { // t*cdag_up*c_up - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, create_up); // Note inverse notation because of notation in operator. - term.coeff *= ptag.second; - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(hopto, destroy_up) ); - this->terms_.push_back(term); - } - { // t*c_up*cdag_up - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, destroy_up); // Note inverse notation because of notation in operator. - term.coeff *= -ptag.second; // Note minus because of anti-commutation - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(hopto, create_up) ); - this->terms_.push_back(term); - } - { // t*cdag_down*c_down - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, create_down); // Note inverse notation because of notation in operator. - term.coeff *= ptag.second; - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(hopto, destroy_down) ); - this->terms_.push_back(term); - } - { // t*c_down*cdag_down - term_descriptor term; - term.is_fermionic = true; - term.coeff = -ti; - - ptag = tag_handler->get_product_tag(fill, destroy_down); // Note inverse notation because of notation in operator. - term.coeff *= -ptag.second; // Note minus because of anti-commutation - - term.push_back( boost::make_tuple(p, ptag.first) ); - term.push_back( boost::make_tuple(hopto, create_down) ); - this->terms_.push_back(term); - } - } - } - - } - - - Index phys; - - Lattice const & lat; - BaseParameters & parms; - - std::shared_ptr > tag_handler; - tag_type create_up, create_down, destroy_up, destroy_down, - count_up, count_down, count, doubly_occ, - ident, fill; - -}; - - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/models_none.hpp b/dmrg/framework/dmrg/models/continuum/models_none.hpp deleted file mode 100644 index 3ca3e3b4f..000000000 --- a/dmrg/framework/dmrg/models/continuum/models_none.hpp +++ /dev/null @@ -1,197 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Bela Bauer - * Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef DMRG_CONTINUOUS_MODELS_NONE_H -#define DMRG_CONTINUOUS_MODELS_NONE_H - -#include - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/utils/BaseParameters.h" - -/* ****************** OPTICAL LATTICE (without symmetry) */ -template -class OpticalLatticeNull : public Model { - typedef Hamiltonian ham; - typedef typename ham::hamterm_t hamterm_t; - typedef Measurement_Term mterm_t; - typedef typename ham::op_t op_t; - typedef typename Matrix::value_type value_type; -public: - OpticalLatticeNull (const Lattice& lat_, BaseParameters & model_) - : lat(lat_) - , model(model_) - { - - throw std::runtime_error("This model is broken, it has to be adapted to the one above..."); - - int phys_size = model["Nmax"]+1; - TrivialGroup::charge c = TrivialGroup::IdentityCharge; - - phys.insert(std::make_pair(c, phys_size)); - ident.insert_block(Matrix::identity_matrix(phys_size), c, c); - count.insert_block(Matrix(phys_size, phys_size, 0), c, c); - interaction.insert_block(Matrix(phys_size, phys_size, 0), c, c); - create.insert_block(Matrix(phys_size, phys_size, 0), c, c); - destroy.insert_block(Matrix(phys_size, phys_size, 0), c, c); - - for (int n=1; n<=model["Nmax"]; ++n) - { - count[0](n, n) = n; - - interaction[0](n, n) = n*n-n; - - create[0](n-1, n) = std::sqrt(value_type(n)); - destroy[0](n, n-1) = std::sqrt(value_type(n)); - } - } - - Index get_phys() const - { - return phys; - } - - Hamiltonian H () const - { - TrivialGroup::charge c = TrivialGroup::IdentityCharge; - - std::vector terms; - for (int p=0; p("x", p)), 2 ); - - double U = model["c"]/lat.get_prop("dx", p); - double mu = ( exp_potential - - model["mu"] - + model["h"]/(lat.get_prop("dx", p)*lat.get_prop("dx", p)) ); - if (!lat.get_prop("at_open_boundary", p)) - mu += model["h"]/(lat.get_prop("dx", p)*lat.get_prop("dx", p)); - - op_t site_op; - site_op.insert_block(U*interaction[0]+mu*count[0], c, c); - - { // site term - hamterm_t term; - term.with_sign = false; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, site_op) ); - terms.push_back(term); - } - - // if (mu != 0) - // { // density term - // hamterm_t term; - // term.fill_operator = ident; - // term.operators.push_back( std::make_pair(p, mu*count) ); - // terms.push_back(term); - // } - // - // if (U != 0) - // { // interaction term - // hamterm_t term; - // term.fill_operator = ident; - // term.operators.push_back( std::make_pair(p, U*interaction) ); - // terms.push_back(term); - // } - - std::vector neighs = lat.forward(p); - for (int n=0; n("dx", p, neighs[n])*lat.get_prop("dx", p, neighs[n])); - - { - hamterm_t term; - term.with_sign = false; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, -t*create) ); - term.operators.push_back( std::make_pair(neighs[n], destroy) ); - terms.push_back(term); - } - { - hamterm_t term; - term.with_sign = false; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, -t*destroy) ); - term.operators.push_back( std::make_pair(neighs[n], create) ); - terms.push_back(term); - } - } - } - - return ham(phys, ident, terms); - } - - Measurements measurements () const - { - Measurements meas; - meas.set_identity(ident); - - if (model["MEASURE_CONTINUUM[Density]"]) { - mterm_t term; - term.fill_operator = ident; - term.name = "Density"; - term.type = mterm_t::Average; - term.operators.push_back( std::make_pair(count, false) ); - - meas.add_term(term); - } - if (model["MEASURE_CONTINUUM[Local density]"]) { - mterm_t term; - term.fill_operator = ident; - term.name = "Local density"; - term.type = mterm_t::Local; - term.operators.push_back( std::make_pair(count, false) ); - - meas.add_term(term); - } - - if (model["MEASURE_CONTINUUM[Onebody density matrix]"]) { - mterm_t term; - term.fill_operator = ident; - term.name = "Onebody density matrix"; - term.type = mterm_t::HalfCorrelation; - term.operators.push_back( std::make_pair(create, false) ); - term.operators.push_back( std::make_pair(destroy, false) ); - - meas.add_term(term); - } - - return meas; - } - -private: - const Lattice & lat; - BaseParameters & model; - - op_t ident; - op_t create, destroy; - op_t count, interaction; - Index phys; -}; - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/models_u1.hpp b/dmrg/framework/dmrg/models/continuum/models_u1.hpp deleted file mode 100644 index 78ea11b10..000000000 --- a/dmrg/framework/dmrg/models/continuum/models_u1.hpp +++ /dev/null @@ -1,284 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2011-2011 by Bela Bauer - * Michele Dolfi - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef DMRG_CONTINUOUS_MODELS_U1_H -#define DMRG_CONTINUOUS_MODELS_U1_H - -#include - -#include - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/utils/BaseParameters.h" - -/* ****************** OPTICAL LATTICE (with symmetry) */ -template -class OpticalLattice : public model_impl -{ - typedef model_impl base; - - typedef typename base::table_type table_type; - typedef typename base::table_ptr table_ptr; - typedef typename base::tag_type tag_type; - - typedef typename base::term_descriptor term_descriptor; - typedef typename base::terms_type terms_type; - typedef typename base::op_t op_t; - typedef typename base::measurements_type measurements_type; - - typedef typename Matrix::value_type value_type; -public: - OpticalLattice (const Lattice& lat_, BaseParameters & model_) - : lat(lat_) - , model(model_) - , tag_handler(new table_type()) - { - int Nmax = model["Nmax"]; - - op_t ident_op; - op_t create_op, destroy_op, count_op, interaction_op; - - phys.insert(std::make_pair(0, 1)); - ident_op.insert_block(Matrix(1, 1, 1), 0, 0); - - for (int n=1; n<=Nmax; ++n) - { - phys.insert(std::make_pair(n, 1)); - - ident_op.insert_block(Matrix(1, 1, 1), n, n); - - count_op.insert_block(Matrix(1, 1, n), n, n); - if ((n*n-n) != 0) - interaction_op.insert_block(Matrix(1, 1, n*n-n), n, n); - - - create_op.insert_block(Matrix(1, 1, std::sqrt(value_type(n))), n-1, n); - destroy_op.insert_block(Matrix(1, 1, std::sqrt(value_type(n))), n, n-1); - } - - - /**********************************************************************/ - /*** Create operator tag table ****************************************/ - /**********************************************************************/ - -#define REGISTER(op, kind) op = tag_handler->register_op(op ## _op, kind); - - REGISTER(ident, tag_detail::bosonic) - REGISTER(create, tag_detail::bosonic) - REGISTER(destroy, tag_detail::bosonic) - REGISTER(count, tag_detail::bosonic) - REGISTER(interaction, tag_detail::bosonic) - -#undef REGISTER - /**********************************************************************/ - - generate_terms(); - } - - void update(BaseParameters const& p) - { - model << p; - generate_terms(); - return; - } - - Index const& phys_dim(size_t type) const - { - return phys; - } - tag_type identity_matrix_tag(size_t type) const - { - return ident; - } - tag_type filling_matrix_tag(size_t type) const - { - return identity_matrix_tag(type); - } - typename U1::charge total_quantum_numbers(BaseParameters & parms) const - { - return static_cast(parms["N_total"]); - } - - tag_type get_operator_tag(std::string const & name, size_t type) const - { - if (name == "n") - return count; - else if (name == "bdag") - return create; - else if (name == "b") - return destroy; - else if (name == "id") - return ident; - else if (name == "fill") - return ident; - else - throw std::runtime_error("Operator not valid for this model."); - return 0; - } - - table_ptr operators_table() const - { - return tag_handler; - } - - measurements_type measurements () const - { - typedef std::vector op_vec; - typedef std::vector > bond_element; - - std::size_t ntypes = lat.maximum_vertex_type()+1; - - measurements_type meas; - - if (model["MEASURE[Density]"]) { - std::string name = "Density"; - meas.push_back( new measurements::average(name, lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - op_vec(ntypes,tag_handler->get_op(count))) ); - } - - if (model["MEASURE[Local density]"]) { - std::string name = "Local density"; - meas.push_back( new measurements::local(name, lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - op_vec(ntypes,tag_handler->get_op(count))) ); - } - - if (model["MEASURE[Onebody density matrix]"]) { - std::string name = "Onebody density matrix"; - bond_element ops; - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(create)), false) ); - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(destroy)), false) ); - meas.push_back( new measurements::correlations(name, lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - ops, true, false) ); - } - - if (model["MEASURE[Density correlation]"]) { - std::string name = "Density correlation"; - bond_element ops; - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(count)), false) ); - ops.push_back( std::make_pair(op_vec(ntypes,tag_handler->get_op(count)), false) ); - meas.push_back( new measurements::correlations(name, lat, - op_vec(ntypes,this->identity_matrix(0)), - op_vec(ntypes,this->filling_matrix(0)), - ops, true, false) ); - } - return meas; - } - -private: - void generate_terms() { - this->terms_.clear(); - - double k = model["k"]; - double V0 = model["V0"]; - double w = model["omega"]; - double shift = model["shift"]; - - - for (int p=0; p neighs = lat.all(p); - - double x = lat.get_prop("x", p); - double exp_potential = V0*std::pow( std::cos(k*x), 2 ); - exp_potential += w*w/2. * std::pow(x - shift, 2 ); - - double dx1 = lat.get_prop("dx", p, neighs[0]); - double dx2; - if (neighs.size() == 1 && lat.get_prop("at_open_left_boundary", p)) - dx2 = lat.get_prop("dx", p, p-1); - else if (neighs.size() == 1 && lat.get_prop("at_open_right_boundary", p)) - dx2 = lat.get_prop("dx", p, p+1); - else - dx2 = lat.get_prop("dx", p, neighs[1]); - - double dx0 = lat.get_prop("dx", p); - - // Psi''(x) = coeff1 * Psi(x+dx1) + coeff0 * Psi(x) + coeff2 * Psi(x+dx2) - double coeff1 = 2. / (dx1*dx1 - dx1*dx2); - double coeff2 = 2. / (dx2*dx2 - dx1*dx2); - double coeff0 = -(coeff1 + coeff2); - - - double U = model["c"] / dx0; - double mu = exp_potential - model["mu"]; - mu += -coeff0 * model["h"]; - - -#ifndef NDEBUG - maquis::cout << "U = " << U << ", mu = " << mu << ", t = " << coeff1 * model["h"] << std::endl; -#endif - - if (U != 0.) - { // interaction - term_descriptor term; - term.coeff = U; - term.push_back( boost::make_tuple(p, interaction) ); - this->terms_.push_back(term); - } - - if (mu != 0.) - { // chemical potential - term_descriptor term; - term.coeff = mu; - term.push_back( boost::make_tuple(p, count) ); - this->terms_.push_back(term); - } - - for (int n=0; n("dx", p, neighs[n]) == dx1) - t = coeff1 * model["h"]; - else - t = coeff2 * model["h"]; - { - term_descriptor term; - term.coeff = -t; - term.push_back( boost::make_tuple(p, create) ); - term.push_back( boost::make_tuple(neighs[n], destroy) ); - this->terms_.push_back(term); - } - } - } - } - - - const Lattice & lat; - BaseParameters & model; - Index phys; - - std::shared_ptr > tag_handler; - tag_type ident, create, destroy, count, interaction; -}; - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/super_models_2u1.hpp b/dmrg/framework/dmrg/models/continuum/super_models_2u1.hpp deleted file mode 100644 index 501639b23..000000000 --- a/dmrg/framework/dmrg/models/continuum/super_models_2u1.hpp +++ /dev/null @@ -1,411 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2013-2013 by Michele Dolfi - * - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef MAQUIS_DMRG_MODELS_CONTINUUM_SUPER_MODELS_2U1_HPP -#define MAQUIS_DMRG_MODELS_CONTINUUM_SUPER_MODELS_2U1_HPP - -#include -#include - -#include "dmrg/block_matrix/grouped_symmetry.h" -#include "dmrg/mp_tensors/mps_sectors.h" -#include "dmrg/mp_tensors/dm_op_kron.h" -#include "dmrg/mp_tensors/identity_mps.h" - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/models/meas_prepare.hpp" -#include "dmrg/utils/BaseParameters.h" - - -template -class mps_ident_init : public mps_initializer -{ -public: - mps_ident_init(MPS const& mps_) - : mps_ident(mps_) - { } - - void operator()(MPS & mps, - std::size_t Mmax, - Index const & phys_rho, - TwoU1::charge right_end) - { - assert( mps.length() == mps_ident.length() ); - assert( right_end == mps_ident[mps.length()-1].col_dim()[0].first ); - - mps = mps_ident; - } - -private: - MPS mps_ident; -}; - - -/* ****************** OPTICAL LATTICE (with symmetry) */ -template -class DMOpticalLatticeTwoU1 : public Model { - typedef Model base; - - typedef Hamiltonian ham; - typedef typename ham::hamterm_t hamterm_t; - typedef typename ham::hamtagterm_t hamtagterm_t; - typedef Measurement_Term mterm_t; - typedef typename ham::op_t op_t; - typedef typename ham::table_type table_type; - typedef typename ham::table_ptr table_ptr; - - typedef Hamiltonian psi_ham; - typedef typename psi_ham::hamterm_t psi_hamterm_t; - typedef typename psi_ham::hamtagterm_t psi_hamtagterm_t; - typedef typename psi_ham::op_t psi_op; - typedef typename psi_ham::table_type psi_table_type; - typedef typename psi_ham::table_ptr psi_table_ptr; - - typedef typename table_type::tag_type tag_type; - typedef typename Matrix::value_type value_type; - -public: - DMOpticalLatticeTwoU1 (const Lattice& lat_, BaseParameters & model_) - : lat(lat_) - , model(model_) - , tag_handler( new table_type() ) - , psi_tag_handler( new psi_table_type() ) - { - psi_op psi_ident_op, psi_count_op, psi_interaction_op, psi_create_op, psi_destroy_op; - op_t ident_op, count_op, interaction_op; - - psi_phys.insert(std::make_pair(0, 1)); - psi_ident_op.insert_block(Matrix(1, 1, 1), 0, 0); - - int Nmax = model["Nmax"]; - for (int n=1; n<=Nmax; ++n) - { - psi_phys.insert(std::make_pair(n, 1)); - - psi_ident_op.insert_block(Matrix(1, 1, 1), n, n); - - psi_count_op.insert_block(Matrix(1, 1, n), n, n); - if ((n*n-n) != 0) - psi_interaction_op.insert_block(Matrix(1, 1, n*n-n), n, n); - - - psi_create_op.insert_block(Matrix(1, 1, std::sqrt(value_type(n))), n-1, n); - psi_destroy_op.insert_block(Matrix(1, 1, std::sqrt(value_type(n))), n, n-1); - } - - /**********************************************************************/ - /*** Create operator tag table ****************************************/ - /**********************************************************************/ -#define REGISTER(op, kind) op = psi_tag_handler->register_op(op ## _op, kind); - REGISTER(psi_ident, tag_detail::bosonic) - REGISTER(psi_create, tag_detail::bosonic) - REGISTER(psi_destroy, tag_detail::bosonic) - REGISTER(psi_count, tag_detail::bosonic) - REGISTER(psi_interaction, tag_detail::bosonic) -#undef REGISTER - /**********************************************************************/ - - - phys = group(psi_phys, adjoin(psi_phys)); - ident_op = identity_matrix(phys); - count_op = adjoint_site_term(psi_count_op); - interaction_op = adjoint_site_term(psi_interaction_op); - - std::cout << "phys: " << phys << std::endl; - std::vector< std::pair > hopops_op = adjoint_bond_term(psi_create_op, psi_destroy_op); - std::vector< std::pair > hopops(hopops_op.size()); - - /**********************************************************************/ - /*** Create operator tag table ****************************************/ - /**********************************************************************/ -#define REGISTER(op, kind) op = tag_handler->register_op(op ## _op, kind); - REGISTER(ident, tag_detail::bosonic) - REGISTER(count, tag_detail::bosonic) - REGISTER(interaction, tag_detail::bosonic) - for (size_t i=0; iregister_op(hopops_op[i].first, tag_detail::bosonic), - tag_handler->register_op(hopops_op[i].second, tag_detail::bosonic) ); -#undef REGISTER - /**********************************************************************/ - - - for (int p=0; p neighs = lat.all(p); - - double exp_potential = model["V0"]*std::pow( std::cos(model["k"]*lat.get_prop("x", p)), 2 ); - - double dx1 = lat.get_prop("dx", p, neighs[0]); - double dx2; - if (neighs.size() == 1 && lat.get_prop("at_open_left_boundary", p)) - dx2 = lat.get_prop("dx", p, p-1); - else if (neighs.size() == 1 && lat.get_prop("at_open_right_boundary", p)) - dx2 = lat.get_prop("dx", p, p+1); - else - dx2 = lat.get_prop("dx", p, neighs[1]); - - double dx0 = lat.get_prop("dx", p); - - // Psi''(x) = coeff1 * Psi(x+dx1) + coeff0 * Psi(x) + coeff2 * Psi(x+dx2) - double coeff1 = 2. / (dx1*dx1 - dx1*dx2); - double coeff2 = 2. / (dx2*dx2 - dx1*dx2); - double coeff0 = -(coeff1 + coeff2); - - double U = model["c"] / dx0; - double mu = exp_potential - model["mu"]; - mu += -coeff0 * model["h"]; - -#ifndef NDEBUG - maquis::cout << "U = " << U << ", mu = " << mu << ", t = " << coeff1 * model["h"] << std::endl; -#endif - - if (U != 0.) - { // U * n * (n-1) - hamtagterm_t term; - term.with_sign = false; - term.scale = U; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, interaction) ); - terms.push_back(term); - } - if (U != 0.) - { // U * n * (n-1) - psi_hamtagterm_t term; - term.with_sign = false; - term.scale = U; - term.fill_operator = psi_ident; - term.operators.push_back( std::make_pair(p, psi_interaction) ); - psi_terms.push_back(term); - } - - if (mu != 0.) - { // mu * n - hamtagterm_t term; - term.with_sign = false; - term.scale = mu; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, count) ); - terms.push_back(term); - } - if (mu != 0.) - { // mu * n - psi_hamtagterm_t term; - term.with_sign = false; - term.scale = mu; - term.fill_operator = psi_ident; - term.operators.push_back( std::make_pair(p, psi_count) ); - psi_terms.push_back(term); - } - - for (int n=0; n("dx", p, neighs[n]) == dx1) - t = coeff1 * model["h"]; - else - t = coeff2 * model["h"]; - - if (t != 0.) { - for( unsigned i = 0; i < hopops.size(); ++i ) - { - hamtagterm_t term; - term.with_sign = false; - term.scale = -t; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, hopops[i].first) ); - term.operators.push_back( std::make_pair(neighs[n], hopops[i].second) ); - terms.push_back(term); - } - } - if (t != 0.) { - psi_hamtagterm_t term; - term.with_sign = false; - term.scale = -t; - term.fill_operator = psi_ident; - term.operators.push_back( std::make_pair(p, psi_create) ); - term.operators.push_back( std::make_pair(neighs[n], psi_destroy) ); - psi_terms.push_back(term); - } - } - } - } - - Index get_phys() const - { - return phys; - } - - Hamiltonian H () const - { - std::vector terms_ops; - return ham(phys, tag_handler->get_op(ident), terms_ops, ident, terms, tag_handler); - } - - Measurements measurements () const - { - Measurements meas(Measurements::Densitymatrix); - typedef DMOverlapMeasurement rho_mterm_t; - meas.set_identity(tag_handler->get_op(ident)); - psi_op const& psi_ident_op = psi_tag_handler->get_op(psi_ident); - - std::vector > allowed_blocks = allowed_sectors(lat.size(), phys, this->initc(model), 1); - - MPS mps_ident = identity_dm_mps(lat.size(), psi_phys, allowed_blocks); - - if (model["MEASURE_CONTINUUM[Density]"]) { - rho_mterm_t term; - term.name = "Density"; - term.type = mterm_t::DMOverlap; - term.mps_ident = mps_ident; - std::vector > ops(1, std::make_pair(psi_tag_handler->get_op(psi_count), false)); - - MPO mpo = meas_prepare::average(lat, psi_ident_op, psi_ident_op, ops); - term.overlaps_mps.push_back( mpo_to_smps_group(mpo, psi_phys, allowed_blocks) ); - - meas.add_term(term); - } - - if (model["MEASURE_CONTINUUM[Local density]"]) { - rho_mterm_t term; - term.name = "Local density"; - term.type = mterm_t::DMOverlap; - term.mps_ident = mps_ident; - std::vector > ops(1, std::make_pair(psi_tag_handler->get_op(psi_count), false)); - - std::pair >, std::vector > tmeas; - tmeas = meas_prepare::local(lat, psi_ident_op, psi_ident_op, ops); - std::swap(tmeas.second, term.labels); - - term.overlaps_mps.reserve(tmeas.first.size()); - for (size_t i=0; i terms_ops; - psi_ham PsiH(psi_phys, psi_ident_op, terms_ops, psi_ident, psi_terms, psi_tag_handler); - MPO mpo = make_mpo(lat.size(), PsiH); - term.overlaps_mps.push_back( mpo_to_smps_group(mpo, psi_phys, allowed_blocks) ); - - meas.add_term(term); - } - -// if (model["MEASURE_CONTINUUM[Onebody density matrix]"]) { -// mterm_t term; -// term.fill_operator = psi_ident; -// term.name = "Onebody density matrix"; -// term.type = mterm_t::HalfCorrelation; -// term.operators.push_back( std::make_pair(psi_create, false) ); -// term.operators.push_back( std::make_pair(psi_destroy, false) ); -// -// meas.add_term(term); -// } - - return meas; - } - - typename base::initializer_ptr initializer(BaseParameters & p_) const - { - if ( p_["init_state"] == "identity_mps" ) { - std::cout << "Identity MPS chosen." << std::endl; - std::vector > allowed_blocks = allowed_sectors(lat.size(), phys, this->initc(model), 1); - return typename base::initializer_ptr( new mps_ident_init( identity_dm_mps(lat.size(), psi_phys, allowed_blocks) ) ); - } else { - return base::initializer(p_); - } - } - - -private: - - op_t adjoint_site_term(psi_op h) const - { - psi_op const& psi_ident_op = psi_tag_handler->get_op(psi_ident); - /// h*rho*1 - 1*rho*h = (1 \otimes h) - (h^T \otimes 1) * rho - /// = rho * (1 \otimes h^T) - (h \otimes 1) - op_t idh, hid; - dm_group_kron(psi_phys, h, psi_ident_op, hid); - h.transpose_inplace(); - dm_group_kron(psi_phys, psi_ident_op, h, idh); - if ( model["RUN_FINITE_T"] ) - return idh; - else - return idh - hid; - } - - std::vector > adjoint_bond_term(psi_op h1, psi_op h2) const - { - psi_op const& psi_ident_op = psi_tag_handler->get_op(psi_ident); - /// 1*rho*h = (h^T \otimes 1) * rho - /// = rho * (h \otimes 1) - op_t h1id, h2id; - dm_group_kron(psi_phys, h1, psi_ident_op, h1id); - dm_group_kron(psi_phys, h2, psi_ident_op, h2id); - - /// h*rho*1 = (1 \otimes h) * rho - /// = rho * (1 \otimes h^T) - op_t idh1, idh2; - h1.transpose_inplace(); - h2.transpose_inplace(); - dm_group_kron(psi_phys, psi_ident_op, h1, idh1); - dm_group_kron(psi_phys, psi_ident_op, h2, idh2); - - std::vector > ret; ret.reserve(2); - ret.push_back( std::make_pair(idh1, idh2) ); - if ( ! static_cast(model["RUN_FINITE_T"]) ) - ret.push_back( std::make_pair(-1.*h1id, h2id) ); - - return ret; - } - - - const Lattice & lat; - BaseParameters & model; - - Index psi_phys; - tag_type psi_ident, psi_count, psi_interaction, psi_create, psi_destroy; - - Index phys; - tag_type ident, count, interaction; - - table_ptr tag_handler; - psi_table_ptr psi_tag_handler; - - std::vector terms; - std::vector psi_terms; -}; - - -#endif diff --git a/dmrg/framework/dmrg/models/continuum/super_models_u1.hpp b/dmrg/framework/dmrg/models/continuum/super_models_u1.hpp deleted file mode 100644 index a6d18039c..000000000 --- a/dmrg/framework/dmrg/models/continuum/super_models_u1.hpp +++ /dev/null @@ -1,307 +0,0 @@ -/***************************************************************************** - * - * ALPS MPS DMRG Project - * - * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich - * 2013-2013 by Michele Dolfi - * - * - * This software is part of the ALPS Applications, published under the ALPS - * Application License; you can use, redistribute it and/or modify it under - * the terms of the license, either version 1 or (at your option) any later - * version. - * - * You should have received a copy of the ALPS Application License along with - * the ALPS Applications; see the file LICENSE.txt. If not, the license is also - * available from http://alps.comp-phys.org/. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -/// Some parts adapted from coded/super_models_none.hpp - -#ifndef DMRG_CONTINUUM_SUPER_MODELS_U1_H -#define DMRG_CONTINUUM_SUPER_MODELS_U1_H - -#include - -#include - -#include "dmrg/models/model.h" -#include "dmrg/models/measurements.h" -#include "dmrg/utils/BaseParameters.h" -#include "dmrg/mp_tensors/dm_op_kron.h" - -/* ****************** OPTICAL LATTICE (with symmetry) */ -template -class DMOpticalLattice : public Model { - typedef Hamiltonian ham; - typedef typename ham::hamterm_t hamterm_t; - typedef Measurement_Term mterm_t; - typedef typename ham::op_t op_t; - typedef typename Matrix::value_type value_type; -public: - DMOpticalLattice (const Lattice& lat_, BaseParameters & model_) - : lat(lat_) - , model(model_) - { - psi_phys.insert(std::make_pair(0, 1)); - psi_ident.insert_block(Matrix(1, 1, 1), 0, 0); - - int Nmax = model["Nmax"]; - for (int n=1; n<=Nmax; ++n) - { - psi_phys.insert(std::make_pair(n, 1)); - - psi_ident.insert_block(Matrix(1, 1, 1), n, n); - - psi_count.insert_block(Matrix(1, 1, n), n, n); - if ((n*n-n) != 0) - psi_interaction.insert_block(Matrix(1, 1, n*n-n), n, n); - - - psi_create.insert_block(Matrix(1, 1, std::sqrt(value_type(n))), n-1, n); - psi_destroy.insert_block(Matrix(1, 1, std::sqrt(value_type(n))), n, n-1); - } - - phys = psi_phys * adjoin(psi_phys); - ident = identity_matrix(phys); - count = adjoint_site_term(psi_count); - interaction = adjoint_site_term(psi_interaction); - - maquis::cout << "phys: " << phys << std::endl; - std::vector< std::pair > hopops = adjoint_bond_term_new(psi_create, psi_destroy); - - for (int p=0; p neighs = lat.all(p); - - double exp_potential = model["V0"]*std::pow( std::cos(model["k"]*lat.get_prop("x", p)), 2 ); - - double dx1 = lat.get_prop("dx", p, neighs[0]); - double dx2; - if (neighs.size() == 1 && lat.get_prop("at_open_left_boundary", p)) - dx2 = lat.get_prop("dx", p, p-1); - else if (neighs.size() == 1 && lat.get_prop("at_open_right_boundary", p)) - dx2 = lat.get_prop("dx", p, p+1); - else - dx2 = lat.get_prop("dx", p, neighs[1]); - - double dx0 = lat.get_prop("dx", p); - - // Psi''(x) = coeff1 * Psi(x+dx1) + coeff0 * Psi(x) + coeff2 * Psi(x+dx2) - double coeff1 = 2. / (dx1*dx1 - dx1*dx2); - double coeff2 = 2. / (dx2*dx2 - dx1*dx2); - double coeff0 = -(coeff1 + coeff2); - - double U = model["c"] / dx0; - double mu = exp_potential - model["mu"]; - mu += -coeff0 * model["h"]; - -#ifndef NDEBUG - maquis::cout << "U = " << U << ", mu = " << mu << ", t = " << coeff1 * model["h"] << std::endl; -#endif - - if (U != 0.) - { // U * n * (n-1) - hamterm_t term; - term.with_sign = false; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, U*interaction) ); - terms.push_back(term); - } - - if (mu != 0.) - { // mu * n - hamterm_t term; - term.with_sign = false; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, mu*count) ); - terms.push_back(term); - } - - for (int n=0; n("dx", p, neighs[n]) == dx1) - t = coeff1 * model["h"]; - else - t = coeff2 * model["h"]; - - if (t != 0.) { - for( unsigned i = 0; i < hopops.size(); ++i ) - { - hamterm_t term; - term.with_sign = false; - term.fill_operator = ident; - term.operators.push_back( std::make_pair(p, -t*hopops[i].first) ); - term.operators.push_back( std::make_pair(neighs[n], hopops[i].second) ); - terms.push_back(term); - } - } - } - } - } - - Index get_phys() const - { - return phys; - } - - Hamiltonian H () const - { - return ham(phys, ident, terms); - } - - Measurements measurements () const - { - Measurements meas(Measurements::Densitymatrix); - meas.set_identity(psi_ident); - - if (model["MEASURE_CONTINUUM[Density]"]) { - mterm_t term; - term.fill_operator = psi_ident; - term.name = "Density"; - term.type = mterm_t::Average; - term.operators.push_back( std::make_pair(psi_count, false) ); - - meas.add_term(term); - } - - if (model["MEASURE_CONTINUUM[Local density]"]) { - mterm_t term; - term.fill_operator = psi_ident; - term.name = "Local density"; - term.type = mterm_t::Local; - term.operators.push_back( std::make_pair(psi_count, false) ); - - meas.add_term(term); - } - - if (model["MEASURE_CONTINUUM[Onebody density matrix]"]) { - mterm_t term; - term.fill_operator = psi_ident; - term.name = "Onebody density matrix"; - term.type = mterm_t::HalfCorrelation; - term.operators.push_back( std::make_pair(psi_create, false) ); - term.operators.push_back( std::make_pair(psi_destroy, false) ); - - meas.add_term(term); - } - - return meas; - } - -private: - - op_t adjoint_site_term(op_t h) const - { - /// h*rho*1 - 1*rho*h = (1 \otimes h) - (h^T \otimes 1) * rho - /// = rho * (1 \otimes h^T) - (h \otimes 1) - op_t idh, hid; - dm_kron(psi_phys, h, psi_ident, hid); - h.transpose_inplace(); - dm_kron(psi_phys, psi_ident, h, idh); - return idh - hid; - } - - std::vector > adjoint_bond_term(op_t const& h1, op_t const& h2) const - { - maquis::cout << "h1:\n" << h1; - maquis::cout << "h2:\n" << h2; - - op_t bond; - op_kron(psi_phys, h1, h2, bond); - maquis::cout << "bond:\n" << bond; - - Index phys2 = psi_phys*psi_phys; - op_t ident_phys2 = identity_matrix(phys2); - - /// h*rho*1 - 1*rho*h = (1 \otimes h) - (h^T \otimes 1) * rho - /// = rho * (1 \otimes h^T) - (h \otimes 1) - op_t idh, hid; - dm_kron(phys2, bond, ident_phys2, hid); - bond.transpose_inplace(); - dm_kron(phys2, ident_phys2, bond, idh); -// maquis::cout << "t1:\n" << t1; -// maquis::cout << "t2:\n" << t2; -// maquis::cout << "transpose(bond):\n" << bond; - bond = idh - hid; - - bond = reshape_2site_op(phys2, bond); - op_t U, V, left, right; - block_matrix::type, U1> S, Ssqrt; - svd(bond, U, V, S); - Ssqrt = sqrt(S); - gemm(U, Ssqrt, left); - gemm(Ssqrt, V, right); - - std::vector leftops = reshape_right_to_list(phys, left); - std::vector rightops = reshape_left_to_list (phys, right); - assert(leftops.size() == rightops.size()); - - std::vector > ret; - - // discard terms with no weight -#ifdef USE_AMBIENT - // Tim 02/15/12 : rewrite this kernel... - assert(false); - printf("FIX std::abs !!! \n"); -#else - size_t j = 0; - for( size_t k = 0; k < S.n_blocks(); ++k ) - for( unsigned i = 0; i < num_rows(S[k]); ++i ) - { - if (std::abs(S[k][i]) > 1e-10) - ret.push_back(std::make_pair( leftops[j], rightops[j] )); - ++j; - } -#endif - return ret; - } - - std::vector > adjoint_bond_term_new(op_t h1, op_t h2) const - { - /// 1*rho*h = (h^T \otimes 1) * rho - /// = rho * (h \otimes 1) - op_t h1id, h2id; - dm_kron(psi_phys, h1, psi_ident, h1id); - dm_kron(psi_phys, h2, psi_ident, h2id); - - /// h*rho*1 = (1 \otimes h) * rho - /// = rho * (1 \otimes h^T) - op_t idh1, idh2; - h1.transpose_inplace(); - h2.transpose_inplace(); - dm_kron(psi_phys, psi_ident, h1, idh1); - dm_kron(psi_phys, psi_ident, h2, idh2); - - std::vector > ret; ret.reserve(2); - ret.push_back( std::make_pair(idh1, idh2) ); - ret.push_back( std::make_pair(-1.*h1id, h2id) ); - - return ret; - } - - - const Lattice & lat; - BaseParameters & model; - - Index psi_phys; - op_t psi_ident, psi_count, psi_interaction, psi_create, psi_destroy; - - Index phys; - op_t ident, count, interaction; - - std::vector terms; -}; - -#endif - diff --git a/dmrg/framework/dmrg/models/factories/factory_2u1.ipp b/dmrg/framework/dmrg/models/factories/factory_2u1.ipp index 35f72da20..722ee0cce 100644 --- a/dmrg/framework/dmrg/models/factories/factory_2u1.ipp +++ b/dmrg/framework/dmrg/models/factories/factory_2u1.ipp @@ -25,7 +25,6 @@ * *****************************************************************************/ -#include "dmrg/models/coded/models_2u1.hpp" #include "dmrg/models/chem/2u1/model.h" #include "dmrg/models/prebo/nu1/model.hpp" #include "dmrg/models/factories/factory.h" @@ -35,10 +34,8 @@ struct coded_model_factory { static std::shared_ptr > parse (Lattice const & lattice, BaseParameters & parms) { - typedef std::shared_ptr > impl_ptr; - if (parms["MODEL"] == std::string("fermion Hubbard")) - return impl_ptr( new FermiHubbardTwoU1(lattice, parms) ); - else if (parms["MODEL"] == std::string("quantum_chemistry")) + using impl_ptr = std::shared_ptr >; + if (parms["MODEL"] == std::string("quantum_chemistry")) return impl_ptr( new qc_model(lattice, parms) ); #ifdef HAVE_NU1 else if (parms["MODEL"] == std::string("PreBO")) diff --git a/dmrg/framework/dmrg/models/factories/factory_su2u1.ipp b/dmrg/framework/dmrg/models/factories/factory_su2u1.ipp index f04dac10a..a25f3e014 100644 --- a/dmrg/framework/dmrg/models/factories/factory_su2u1.ipp +++ b/dmrg/framework/dmrg/models/factories/factory_su2u1.ipp @@ -25,20 +25,15 @@ * *****************************************************************************/ -#include "dmrg/models/coded/models_su2.hpp" #include "dmrg/models/chem/su2u1/model.h" #include "dmrg/models/factories/factory.h" template struct coded_model_factory { - static std::shared_ptr > parse - (Lattice const & lattice, BaseParameters & parms) + static std::shared_ptr > parse(Lattice const & lattice, BaseParameters & parms) { - typedef std::shared_ptr > impl_ptr; - if (parms["MODEL"] == std::string("fermion Hubbard")) - return impl_ptr( new FermiHubbardSU2(lattice, parms) ); - - else if (parms["MODEL"] == std::string("quantum_chemistry")) + using impl_ptr = std::shared_ptr >; + if (parms["MODEL"] == std::string("quantum_chemistry")) return impl_ptr( new qc_su2(lattice, parms) ); else { diff --git a/dmrg/framework/dmrg/models/generate_mpo/1D_mpo_maker.hpp b/dmrg/framework/dmrg/models/generate_mpo/1D_mpo_maker.hpp index d4be59465..2ed1236e7 100644 --- a/dmrg/framework/dmrg/models/generate_mpo/1D_mpo_maker.hpp +++ b/dmrg/framework/dmrg/models/generate_mpo/1D_mpo_maker.hpp @@ -132,7 +132,7 @@ namespace generate_mpo range_end++; } - term.push_back( boost::make_tuple(pos_ops[opnr].first, product) ); + term.push_back( std::make_pair(pos_ops[opnr].first, product) ); opnr = range_end; } @@ -163,8 +163,6 @@ namespace generate_mpo typedef term_descriptor term_descriptor; typedef typename OPTable::tag_type tag_type; - using boost::tuples::get; - MPO ret(lat.size()); bool carry_sign = false; @@ -173,9 +171,9 @@ namespace generate_mpo typename MPOTensor::prempo_t prempo; // check if there is a non-trivial operator on site p - typename term_descriptor::const_iterator - it = std::find_if(term.begin(), term.end(), - boost::bind(detail::get<0, typename term_descriptor::value_type>, boost::lambda::_1) == p); + auto it = std::find_if(term.begin(), term.end(), [&p](const auto& iInput) { + return iInput.first == p; + }); if (it != term.end()) // if yes { diff --git a/dmrg/framework/dmrg/models/generate_mpo/tagged_mpo_maker_optim.hpp b/dmrg/framework/dmrg/models/generate_mpo/tagged_mpo_maker_optim.hpp index 0999f7e4e..2e92b607e 100644 --- a/dmrg/framework/dmrg/models/generate_mpo/tagged_mpo_maker_optim.hpp +++ b/dmrg/framework/dmrg/models/generate_mpo/tagged_mpo_maker_optim.hpp @@ -100,12 +100,6 @@ namespace generate_mpo return os; } - template - std::pair to_pair(boost::tuple const& t) - { - return std::make_pair( boost::get<0>(t), boost::get<1>(t) ); - } - /** * @brief TaggedMPOMaker class * @@ -218,11 +212,11 @@ namespace generate_mpo break; } - leftmost_right = std::min(leftmost_right, boost::get<0>(*term.rbegin())); - rightmost_left = std::max(rightmost_left, boost::get<0>(*term.begin())); + leftmost_right = std::min(leftmost_right, term.rbegin()->first); + rightmost_left = std::max(rightmost_left, term.begin()->first); } - - /** @brief Creates the MPO based on the tagged MPO object */ + + /** @bref Creates the MPO based on the tagged MPO object */ MPO create_mpo() { if (!finalized) finalize(); @@ -240,10 +234,8 @@ namespace generate_mpo for (pos_t p = 0; p < length; ++p) { std::vector pre_tensor; pre_tensor.reserve(prempo[p].size()); - std::map HermKeyPairs; std::map > HermitianPhases; - index_map right; index_type r = 2; for (typename prempo_map_type::const_iterator it = prempo[p].begin(); it != prempo[p].end(); ++it) { @@ -383,14 +375,14 @@ namespace generate_mpo int i = 0; mpo_spin = couple(mpo_spin, (tag_handler->get_op(term.operator_tag(i))).spin()); prempo_key_type k2; - k2.pos_op.push_back(to_pair(term[i+1])); + k2.pos_op.push_back(term[i+1]); k1 = insert_operator(term.position(i), make_pair(k1, k2), prempo_value_type(term.operator_tag(i), term.coeff), detach); if (tag_handler->is_fermionic(term.operator_tag(i))) v_nferm[v_part_type[i]] -= 1; v_trivial_fill[v_part_type[i]] = (v_nferm[v_part_type[i]] % 2 == 0); } bool trivial_fill = !tag_handler->is_fermionic(term.operator_tag(1)); - insert_filling(term.position(0)+1, term.position(1), k1, v_trivial_fill, (mpo_spin.get() > 1) ? term.full_identity : -1); + insert_filling(term.position(0)+1, term.position(1), k1, v_trivial_fill, mpo_spin.get() > 1); // Second term { int i = 1; @@ -551,7 +543,7 @@ namespace generate_mpo prempo_key_type k1 = trivial_left; for (std::size_t i = 0; i < thresh; ++i) { mpo_spin = couple(mpo_spin, (tag_handler->get_op(term.operator_tag(i))).spin()); - ops_left.push_back(to_pair(term[i])); + ops_left.push_back(term[i]); prempo_key_type k2(ops_left); k1 = insert_operator(term.position(i), make_pair(k1, k2), prempo_value_type(term.operator_tag(i), 1.), attach); // Checks how many fermionic operators are left - if the number is odd, will insert the filling, @@ -560,14 +552,13 @@ namespace generate_mpo v_nferm[v_part_type[i]] -= 1; v_trivial_fill[v_part_type[i]] = (v_nferm[v_part_type[i]] % 2 == 0); // -> if types at term.position(i) and term.position(i+1) are different insert trivial fill - insert_filling(term.position(i)+1, term.position(i+1), k1, v_trivial_fill, (mpo_spin.get() > 1) ? - term.full_identity : -1); + insert_filling(term.position(i)+1, term.position(i+1), k1, v_trivial_fill, mpo_spin.get() > 1); } // == MIDDLE OPERATOR == // Note that in this case we use the detach modality prempo_key_type k2; for (std::size_t j = thresh+1; j < nops; j++) - ops_right.push_back(to_pair(term[j])); + ops_right.push_back(term[j]); k2 = prempo_key_type(ops_right); mpo_spin = couple(mpo_spin, (tag_handler->get_op(term.operator_tag(thresh))).spin()); k1 = insert_operator(term.position(thresh), make_pair(k1, k2), prempo_value_type(term.operator_tag(thresh), term.coeff), detach); @@ -575,8 +566,7 @@ namespace generate_mpo if (tag_handler->is_fermionic(term.operator_tag(thresh))) v_nferm[v_part_type[thresh]] -= 1; v_trivial_fill[v_part_type[thresh]] = (v_nferm[v_part_type[thresh]] % 2 == 0); - insert_filling(term.position(thresh)+1, term.position(thresh+1), k1, v_trivial_fill, (mpo_spin.get() > 1) ? - term.full_identity : -1); + insert_filling(term.position(thresh)+1, term.position(thresh+1), k1, v_trivial_fill, mpo_spin.get() > 1); // == MERGE OPERATOR == for (std::size_t i = thresh+1; i < nops; i++) { // Extract position and then type @@ -586,7 +576,7 @@ namespace generate_mpo k2 = trivial_right; } else { for (int j = i+1; j < nops; j++) - ops_right.push_back(to_pair(term[j])); + ops_right.push_back(term[j]); k2 = prempo_key_type(ops_right); } mpo_spin = couple(mpo_spin, (tag_handler->get_op(term.operator_tag(i))).spin()); @@ -596,8 +586,7 @@ namespace generate_mpo v_nferm[v_part_type[i]] -= 1; if ( i != nops-1 ) { v_trivial_fill[v_part_type[i]] = (v_nferm[v_part_type[i]] % 2 == 0); - insert_filling(term.position(i)+1, term.position(i+1), k1, v_trivial_fill, (mpo_spin.get() > 1) ? - term.full_identity : -1); + insert_filling(term.position(i)+1, term.position(i+1), k1, v_trivial_fill, mpo_spin.get() > 1); } } // Final term, the only one where the coefficient is actually employed @@ -622,7 +611,7 @@ namespace generate_mpo prempo_key_type k1 = trivial_left; prempo_key_type k2(prempo_key_type::bulk_no_merge, current_offset); - k2.pos_op.push_back( to_pair(term[nops-1]) ); + k2.pos_op.push_back(term[nops-1]); { int i = 0; @@ -646,24 +635,34 @@ namespace generate_mpo } - void insert_filling(pos_t i, pos_t j, prempo_key_type k, std::vector trivial_fill, int custom_ident = -1) - { - for (; i < j; ++i) { + /** + * @brief Insert proper the filling operators between sites i and j. + * @param i starting site + * @param j ending site + * @param k prempo_key_type associated with the operator to be propagated + * @param trivial_fill vector of bool with size == number of particle types indicating whether the identity or + * the filling operator should be used + * @param isSpinLargerThanOne if true, uses the identity full operator instead of the "simpler" identity + */ + void insert_filling(pos_t i, pos_t j, prempo_key_type k, std::vector trivial_fill, bool isSpinLargerThanOne) + { + for (; i < j; ++i) { auto typei = lat.get_prop("type", i); auto particleTypei = lat.get_prop("ParticleType", i); - tag_type use_ident = (custom_ident != -1) ? identities_full[typei] : identities[typei]; + tag_type use_ident = (isSpinLargerThanOne) ? identities_full[typei] : identities[typei]; tag_type op = (trivial_fill[particleTypei]) ? use_ident : fillings[typei]; - //std::pair ret = prempo[i].insert( make_pair(make_pair(k,k), prempo_value_type(op, 1.)) ); - //if (!ret.second && ret.first->second.first != op) - if (prempo[i].count(make_pair(k,k)) == 0) - typename prempo_map_type::iterator ret = prempo[i].insert( make_pair(make_pair(k,k), prempo_value_type(op, 1.)) ); - else { + //std::pair ret = prempo[i].insert( make_pair(make_pair(k,k), prempo_value_type(op, 1.)) ); + //if (!ret.second && ret.first->second.first != op) + if (prempo[i].count(make_pair(k,k)) == 0) { + auto ret = prempo[i].insert( make_pair(make_pair(k,k), prempo_value_type(op, 1.)) ); + } + else { if (prempo[i].find(make_pair(k,k))->second != prempo_value_type(op, 1.)) - throw std::runtime_error("Pre-existing term at site "+std::to_string(i)+ ". Needed "+std::to_string(op) - + ", found "+std::to_string(prempo[i].find(make_pair(k,k))->second.first)); + throw std::runtime_error("Pre-existing term at site "+std::to_string(i)+ ". Needed "+std::to_string(op) + + ", found "+std::to_string(prempo[i].find(make_pair(k,k))->second.first)); } - } - } + } + } /** * @brief Method to insert an element in the prempo objecj @@ -672,11 +671,11 @@ namespace generate_mpo * @param prempo_value_type val: element to be added on site p * @param merge_kind merge_behaviour: detach if a new branch should not be created, attach otherwise */ - prempo_key_type insert_operator(pos_t p, std::pair kk, prempo_value_type val, + prempo_key_type insert_operator(pos_t p, std::pair kk, prempo_value_type val, merge_kind merge_behavior=detach) - { - /// merge_behavior == detach: a new branch will be created, in case op already exist, an offset is used - /// merge_behavior == attach: if operator tags match, keep the same branch + { + /// merge_behavior == detach: a new branch will be created, in case op already exist, an offset is used + /// merge_behavior == attach: if operator tags match, keep the same branch if (merge_behavior == detach) prempo[p].insert( make_pair(kk, val) ); else @@ -684,7 +683,7 @@ namespace generate_mpo prempo[p].insert( make_pair(kk, val) ); return kk.second; - } + } /** * @brief Performs final operations on the prempo object. @@ -699,9 +698,9 @@ namespace generate_mpo for (typename std::map::const_iterator it = site_terms.begin(); it != site_terms.end(); ++it) { tag_type site_tag = tag_handler->register_op(it->second, tag_detail::bosonic); - //std::pair ret; + //std::pair ret; //ret = prempo[it->first].insert( make_pair( kk, prempo_value_type(site_tag,1.) ) ); - typename prempo_map_type::iterator ret; + typename prempo_map_type::iterator ret; ret = prempo[it->first].insert( make_pair( kk, prempo_value_type(site_tag,1.) ) ); if (prempo[it->first].count(ret->first) != 1) throw std::runtime_error("another site term already existing!"); diff --git a/dmrg/framework/dmrg/models/generate_mpo/utils.hpp b/dmrg/framework/dmrg/models/generate_mpo/utils.hpp index 8a8235a34..51219c9c7 100644 --- a/dmrg/framework/dmrg/models/generate_mpo/utils.hpp +++ b/dmrg/framework/dmrg/models/generate_mpo/utils.hpp @@ -230,10 +230,10 @@ namespace generate_mpo } struct pos_tag_lt { - typedef boost::tuple value_type; + typedef std::pair value_type; inline bool operator() (value_type const& lhs, value_type const& rhs) { - return (boost::get<0>(lhs) < boost::get<0>(rhs)); + return (lhs.first < rhs.first); } }; } diff --git a/dmrg/framework/dmrg/models/lattice_factory.cpp b/dmrg/framework/dmrg/models/lattice_factory.cpp index 83f6d5b20..4d4ae4e2a 100644 --- a/dmrg/framework/dmrg/models/lattice_factory.cpp +++ b/dmrg/framework/dmrg/models/lattice_factory.cpp @@ -26,7 +26,6 @@ #include "dmrg/models/lattice.h" #include "dmrg/models/factories/factory_lattice.hpp" -#include "dmrg/models/continuum/factory_lattice.hpp" #ifdef ENABLE_ALPS_MODELS #include "dmrg/models/alps/lattice.hpp" @@ -50,8 +49,6 @@ lattice_factory(BaseParameters & parms) #else throw std::runtime_error("This code was compiled without alps lattice."); #endif - } else if (parms["lattice_library"] == "continuum") { - return cont_lattice_factory(parms); #ifdef ENABLE_LL_MODELS } else if (parms["lattice_library"] == "ll") { return ll_lattice_factory(parms); diff --git a/dmrg/framework/dmrg/models/measurements/tagged_nrankrdm.h b/dmrg/framework/dmrg/models/measurements/tagged_nrankrdm.h index 3ff78798c..03f568d3c 100644 --- a/dmrg/framework/dmrg/models/measurements/tagged_nrankrdm.h +++ b/dmrg/framework/dmrg/models/measurements/tagged_nrankrdm.h @@ -168,10 +168,12 @@ namespace measurements { { // Test if a separate bra state has been specified bool bra_neq_ket = (dummy_bra_mps.length() > 0); - MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + //MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS ket_mps_local = ket_mps; #ifdef MAQUIS_OPENMP - #pragma omp parallel for schedule(dynamic) + #pragma omp parallel for schedule(dynamic) firstprivate(ket_mps_local, bra_mps) #endif for (std::size_t i = 0; i < positions_first.size(); ++i) { pos_t p1 = positions_first[i]; @@ -197,7 +199,7 @@ namespace measurements { if(measurements_details::checkpg()(term, tag_handler_local, lattice)) { MPO mpo = generate_mpo::sign_and_fill(term, identities, fillings, tag_handler_local, lattice); - value += operator_terms[synop].second * expval(bra_mps, ket_mps, mpo); + value += operator_terms[synop].second * expval(bra_mps, ket_mps_local, mpo); } } @@ -231,7 +233,10 @@ namespace measurements { { // Test if a separate bra state has been specified bool bra_neq_ket = (dummy_bra_mps.length() > 0); bool bra_neq_ket = (dummy_bra_mps.length() > 0); - MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + + //MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS ket_mps_local = ket_mps; // Obtain the total number of RDM elements and the list of all indices (eventually for a given slice) auto indices = measurements_details::iterate_nrdm(lattice.size(), bra_neq_ket, positions_first); @@ -242,7 +247,7 @@ namespace measurements { // Loop over all indices #ifdef MAQUIS_OPENMP - #pragma omp parallel for schedule(dynamic) + #pragma omp parallel for schedule(dynamic) firstprivate(bra_mps, ket_mps_local) #endif for (int i = 0; i < indices.size(); i++) @@ -260,7 +265,7 @@ namespace measurements { std::shared_ptr > tag_handler_local(new TagHandler(*tag_handler)); // Setup MPO and calculate the expectation value for a given indices set - this->vector_results[i] = nrdm_expval(N, bra_mps, ket_mps, positions, tag_handler_local); + this->vector_results[i] = nrdm_expval(N, bra_mps, ket_mps_local, positions, tag_handler_local); } // iterator loop } @@ -397,10 +402,11 @@ namespace measurements { { // Test if a separate bra state has been specified bool bra_neq_ket = (dummy_bra_mps.length() > 0); - MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; - + //MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS ket_mps_local = ket_mps; #ifdef MAQUIS_OPENMP - #pragma omp parallel for schedule(dynamic) + #pragma omp parallel for schedule(dynamic) firstprivate(bra_mps, ket_mps_local) #endif for (std::size_t i = 0; i < positions_first.size(); ++i) { pos_t p1 = positions_first[i]; @@ -413,16 +419,17 @@ namespace measurements { std::vector positions = {p1, p2}; std::vector terms; - if (p1 != p2) + if (p1 != p2) { // The sqrt(2.) balances the magnitudes of Clebsch coeffs C^{1/2 1/2 0}_{mrm'} which apply at the second spin-1/2 operator terms.push_back(TermMakerSU2::positional_two_term( true, op_collection.ident.no_couple, std::sqrt(2.), p1, p2, op_collection.create.couple_down, op_collection.create.fill_couple_up, op_collection.destroy.couple_down, op_collection.destroy.fill_couple_up, lattice )); + } else { term_descriptor term; term.coeff = 1.; - term.push_back( boost::make_tuple(p1, op_collection.count.no_couple[lattice.get_prop("type", p1)]) ); + term.push_back( std::make_pair(p1, op_collection.count.no_couple[lattice.get_prop("type", p1)]) ); terms.push_back(term); } @@ -433,7 +440,7 @@ namespace measurements { generate_mpo::TaggedMPOMaker mpo_m(lattice, op_collection.ident.no_couple, op_collection.ident_full.no_couple, op_collection.fill.no_couple, tag_handler_local, terms); MPO mpo = mpo_m.create_mpo(); - typename MPS::scalar_type value = expval(bra_mps, ket_mps, mpo); + typename MPS::scalar_type value = expval(bra_mps, ket_mps_local, mpo); dct.push_back(value); @@ -467,7 +474,9 @@ namespace measurements { { // Test if a separate bra state has been specified bool bra_neq_ket = (dummy_bra_mps.length() > 0); - MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + //MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS ket_mps_local = ket_mps; // get all the labels ahead of the measurement and initialise the result arrays with the correct size auto indices = measurements_details::iterate_nrdm<2>(lattice.size(), bra_neq_ket); @@ -476,7 +485,7 @@ namespace measurements { this->vector_results.resize(indices.size()); #ifdef MAQUIS_OPENMP - #pragma omp parallel for schedule(dynamic) + #pragma omp parallel for schedule(dynamic) firstprivate(ket_mps_local, bra_mps) #endif for (int i = 0; i < indices.size(); i++) { @@ -502,7 +511,7 @@ namespace measurements { generate_mpo::TaggedMPOMaker mpo_m(lattice, op_collection.ident.no_couple, op_collection.ident_full.no_couple, op_collection.fill.no_couple, tag_handler_local, terms); MPO mpo = mpo_m.create_mpo(); - typename MPS::scalar_type value = expval(bra_mps, ket_mps, mpo); + typename MPS::scalar_type value = expval(bra_mps, ket_mps_local, mpo); // save results this->vector_results[i] = value; @@ -606,10 +615,12 @@ namespace measurements { { // Test if a separate bra state has been specified bool bra_neq_ket = (dummy_bra_mps.length() > 0); - MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + //MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS ket_mps_local = ket_mps; #ifdef MAQUIS_OPENMP - #pragma omp parallel for schedule(dynamic) + #pragma omp parallel for schedule(dynamic) firstprivate(ket_mps_local, bra_mps) #endif for (std::size_t i = 0; i < positions_first.size(); ++i) { pos_t p1 = positions_first[i]; @@ -631,7 +642,7 @@ namespace measurements { //if(measurements_details::checkpg()(term, tag_handler_local, lattice)) { MPO mpo = generate_mpo::sign_and_fill(term, identities, fillings, tag_handler_local, lattice); - typename MPS::scalar_type value = operator_terms[0].second * expval(bra_mps, ket_mps, mpo); + typename MPS::scalar_type value = operator_terms[0].second * expval(bra_mps, ket_mps_local, mpo); dct.push_back(value); num_labels.push_back(order_labels(lattice, positions)); @@ -666,10 +677,12 @@ namespace measurements { { // Test if a separate bra state has been specified bool bra_neq_ket = (dummy_bra_mps.length() > 0); - MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + //MPS const & bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS bra_mps = (bra_neq_ket) ? dummy_bra_mps : ket_mps; + MPS ket_mps_local = ket_mps; #ifdef MAQUIS_OPENMP - #pragma omp parallel for collapse(1) schedule(dynamic) + #pragma omp parallel for collapse(1) schedule(dynamic) firstprivate(ket_mps_local, bra_mps) #endif for (pos_t p1 = 0; p1 < lattice.size(); ++p1) for (pos_t p2 = 0; p2 < lattice.size(); ++p2) @@ -718,7 +731,8 @@ namespace measurements { measured = true; MPO mpo = generate_mpo::sign_and_fill(term, identities, fillings, tag_handler_local, lattice); //value += operator_terms[synop].second * expval(bra_mps, ket_mps, mpo); - value += (this->cast_to_real) ? maquis::real(operator_terms[synop].second * expval(bra_mps, ket_mps, mpo)) : operator_terms[synop].second * expval(bra_mps, ket_mps, mpo); + value += (this->cast_to_real) ? maquis::real(operator_terms[synop].second * expval(bra_mps, ket_mps_local, mpo)) + : operator_terms[synop].second * expval(bra_mps, ket_mps, mpo); } if(measured) diff --git a/dmrg/framework/dmrg/models/model_factory.ipp b/dmrg/framework/dmrg/models/model_factory.ipp index 70546bc24..d196dfcd3 100644 --- a/dmrg/framework/dmrg/models/model_factory.ipp +++ b/dmrg/framework/dmrg/models/model_factory.ipp @@ -26,7 +26,6 @@ #include "dmrg/models/model.h" #include "dmrg/models/factories/factory.h" -#include "dmrg/models/continuum/factory.h" #include "dmrg/models/initializer_factory.h" #ifdef ENABLE_ALPS_MODELS @@ -42,7 +41,6 @@ template std::shared_ptr > \ model_factory(Lattice const&, BaseParameters &); - // Implementation template std::shared_ptr > @@ -59,15 +57,8 @@ model_factory(Lattice const& lattice, BaseParameters & parms) #endif } else if (parms["model_library"] == "coded") { return coded_model_factory::parse(lattice, parms); - } else if (parms["model_library"] == "continuum") { - return cont_model_factory::parse(lattice, parms); -//#ifdef ENABLE_LL_MODELS -// } else if (parms["model_library"] == "ll") { -// return ll_model_factory::parse(lattice, parms); -//#endif } else { throw std::runtime_error("Don't know this model_library!"); } -} - +} \ No newline at end of file diff --git a/dmrg/framework/dmrg/models/prebo/model_helper.hpp b/dmrg/framework/dmrg/models/prebo/model_helper.hpp index 22e9d5cc4..a4bbf5cb5 100644 --- a/dmrg/framework/dmrg/models/prebo/model_helper.hpp +++ b/dmrg/framework/dmrg/models/prebo/model_helper.hpp @@ -85,7 +85,7 @@ class modelHelper { scaling *= scale; range_end++; } - term.push_back(boost::make_tuple(pos_ops[opnr].first, product)); + term.push_back(std::make_pair(pos_ops[opnr].first, product)); opnr = range_end; } // std::cout << "Overall scaling" << std::endl; diff --git a/dmrg/framework/dmrg/models/term_descriptor.h b/dmrg/framework/dmrg/models/term_descriptor.h index 4c7255f22..2cb513211 100644 --- a/dmrg/framework/dmrg/models/term_descriptor.h +++ b/dmrg/framework/dmrg/models/term_descriptor.h @@ -4,6 +4,7 @@ * * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich * 2013-2013 by Michele Dolfi + * 2021 by Alberto Baiardi * * This software is part of the ALPS Applications, published under the ALPS * Application License; you can use, redistribute it and/or modify it under @@ -27,85 +28,78 @@ #ifndef MODELS_TERM_DESCRIPTOR_H #define MODELS_TERM_DESCRIPTOR_H -#include +#include #include namespace detail { - struct pos_tag_lt { - typedef boost::tuple value_type; - inline bool operator() (value_type const& lhs, value_type const& rhs) - { - return (boost::get<0>(lhs) < boost::get<0>(rhs)); - } - }; +struct pos_tag_lt { + using value_type = std::pair; + inline bool operator() (value_type const& lhs, value_type const& rhs) + { + return (lhs.first < rhs.first); + } +}; } +/** + * @brief Term descriptor class + * + * The term descriptor class represents an entry of an operators expressed in second-quantization. + * The underlying data type is a vector of pairs (int, int). The first element of the pair is + * the site on which the operator acts, and the second element is the tag of the corresponding elementary + * operator. + * + * @tparam T Scalar type underlying the operator. + */ template -class term_descriptor : public std::vector > { +class term_descriptor : public std::vector > { public: - typedef int pos_type; - typedef unsigned int tag_type; - typedef boost::tuple value_type; - - typedef std::vector base; - typedef base::size_type size_type; - typedef typename base::iterator iterator; - typedef typename base::const_iterator const_iterator; + // Types definition + using pos_type = int; + using tag_type = unsigned int; + using value_type = std::pair; + using base = std::vector; + using size_type = base::size_type; + using iterator = typename base::iterator; + using const_iterator = typename base::const_iterator; - T coeff; - bool is_fermionic; - tag_type full_identity; + /** @brief Class constructor */ term_descriptor() : base(), coeff(1.), is_fermionic(false) { } - pos_type position(size_type i) const { return boost::get<0>((*this)[i]); } - tag_type operator_tag(size_type i) const { return boost::get<1>((*this)[i]); } + /** @brief Getter for the position */ + pos_type position(size_type i) const { return this->operator[](i).first; } + + /** @brief Getter for the operator */ + tag_type operator_tag(size_type i) const { return this->operator[](i).second; } - /// utilities - void canonical_order() // TODO: check and fix for fermions - { - std::sort(begin(), end(), detail::pos_tag_lt()); - } + /** @brief Sorting of the operators */ + // TODO: check and fix for fermions + void canonical_order() { std::sort(begin(), end(), detail::pos_tag_lt()); } + /** @brief Comparison operator */ bool operator< (term_descriptor const & rhs) const { - if (this->size() == 0 && rhs.size() == 0) return false; - if (this->size() == 0) return true; - if (rhs.size() == 0) return false; - + if (this->size() == 0 && rhs.size() == 0) + return false; + if (this->size() == 0) + return true; + if (rhs.size() == 0) + return false; if (this->position(0) == rhs.position(0)) return this->size() > rhs.size(); return this->position(0) < rhs.position(0); } - - bool site_match (term_descriptor const & rhs) const - { - if (this->size() == rhs.size()) - { - bool ret = true; - for (std::size_t p=0; psize() && ret; ++p) - ret = (this->position(p) == rhs.position(p)); - return ret; - } else if (this->size() == 2 && rhs.size() == 1) - return (this->position(0) == rhs.position(0) || this->position(1) == rhs.position(0)); - else if (this->size() == 1 && rhs.size() == 2) - return (this->position(0) == rhs.position(0) || this->position(0) == rhs.position(1)); - else - { - throw std::runtime_error("site_match not implemented for this type of operator." ); - return false; - } - - } - - bool overlap (term_descriptor const & rhs) const - { - return !( (boost::get<0>(*this->rbegin()) < boost::get<0>(*rhs.begin())) || (boost::get<0>(*rhs.rbegin()) < boost::get<0>(*this->begin())) ); - } + + // Class members + /** Scaling factor for the operator term */ + T coeff; + /** True for fermionic operators */ + bool is_fermionic; }; -/// ostream +// ostream template std::ostream & operator<< (std::ostream & os, term_descriptor const& term) { diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/apply_op.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/apply_op.hpp index 779603837..053e53d25 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/apply_op.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/apply_op.hpp @@ -35,50 +35,46 @@ #include "dmrg/mp_tensors/contractions/abelian/detail.hpp" namespace contraction { - namespace abelian { - - using ::contraction::ContractionGrid; - using ::contraction::common::BoundaryMPSProduct; - using ::contraction::common::MPSBoundaryProduct; - - template - void lbtm_kernel_allocate(size_t b2, - ContractionGrid& contr_grid, - Boundary const & left, - BoundaryMPSProduct const & left_mult_mps, - MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_left_basis, - Index const & right_i, - Index const & out_left_i) - { - typedef typename MPOTensor::index_type index_type; - typedef typename MPOTensor::col_proxy col_proxy; - - typedef typename SymmGroup::charge charge; - typedef std::size_t size_t; - - col_proxy col_b2 = mpo.column(b2); - for (typename col_proxy::const_iterator col_it = col_b2.begin(); col_it != col_b2.end(); ++col_it) { - index_type b1 = col_it.index(); - - DualIndex T_basis = detail::T_basis_left(left, left_mult_mps, mpo, ket_basis, ref_left_basis, b1); - if (T_basis.size() == 0) continue; - - MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); +namespace abelian { + +using ::contraction::ContractionGrid; +using ::contraction::common::BoundaryMPSProduct; +using ::contraction::common::MPSBoundaryProduct; + +template +void lbtm_kernel_allocate(size_t b2, ContractionGrid& contr_grid, + Boundary const & left, + BoundaryMPSProduct const & left_mult_mps, + MPOTensor const & mpo, + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & right_i, Index const & out_left_i, + bool isHermitian=true) +{ + typedef typename MPOTensor::index_type index_type; + typedef typename MPOTensor::col_proxy col_proxy; + typedef typename SymmGroup::charge charge; + typedef std::size_t size_t; + col_proxy col_b2 = mpo.column(b2); + for (typename col_proxy::const_iterator col_it = col_b2.begin(); col_it != col_b2.end(); ++col_it) { + index_type b1 = col_it.index(); + DualIndex T_basis = detail::T_basis_left(left, left_mult_mps, mpo, ket_basis, bra_basis, b1, isHermitian); + if (T_basis.size() == 0) + continue; + MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); for (size_t oi = 0; oi < access.size(); ++oi) { - typename operator_selector::type const & W = access.op(oi); if(W.n_blocks() == 0) continue; - + typename operator_selector::type const & W = access.op(oi); + if(W.n_blocks() == 0) + continue; charge operator_delta = SymmGroup::fuse(W.basis().right_charge(0), -W.basis().left_charge(0)); charge T_delta = SymmGroup::fuse(T_basis.right_charge(0), -T_basis.left_charge(0)); charge total_delta = SymmGroup::fuse(operator_delta, -T_delta); - block_matrix& ret = contr_grid(b1,b2); - - for(size_t r = 0; r < right_i.size(); ++r){ + for(size_t r = 0; r < right_i.size(); ++r) { charge out_r_charge = right_i[r].first; - charge out_l_charge = SymmGroup::fuse(out_r_charge, total_delta); if(!out_left_i.has(out_l_charge)) continue; + charge out_l_charge = SymmGroup::fuse(out_r_charge, total_delta); + if(!out_left_i.has(out_l_charge)) + continue; size_t r_size = right_i[r].second; if(ret.find_block(out_l_charge, out_r_charge) == ret.n_blocks()) #ifdef USE_AMBIENT @@ -90,60 +86,52 @@ namespace contraction { #endif } } // oi - } // b1 - contr_grid.index_sizes(b2); - } - - // SK: New version which generates same output but uses right-paired input. - // The charge delta optimization is indepent from the changes needed to - // skip the preceding reshapes. - template - void lbtm_kernel_execute(size_t b2, - ContractionGrid& contr_grid, - Boundary const & left, - BoundaryMPSProduct const & left_mult_mps, - MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & right_i, - Index const & out_left_i, - ProductBasis const & in_right_pb, - ProductBasis const & out_left_pb) - { - typedef typename MPOTensor::index_type index_type; - typedef typename MPOTensor::col_proxy col_proxy; - - typedef typename SymmGroup::charge charge; - typedef std::size_t size_t; - - col_proxy col_b2 = mpo.column(b2); - for (typename col_proxy::const_iterator col_it = col_b2.begin(); col_it != col_b2.end(); ++col_it) { - index_type b1 = col_it.index(); - - //block_matrix const & T = left_mult_mps[b1]; if(T.n_blocks() == 0) continue; - block_matrix local; - block_matrix const & T = left_mult_mps.at(b1, local); - if(T.n_blocks() == 0) continue; - - MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); - + } // b1 + contr_grid.index_sizes(b2); +} + +// SK: New version which generates same output but uses right-paired input. +// The charge delta optimization is indepent from the changes needed to +// skip the preceding reshapes. +template +void lbtm_kernel_execute(size_t b2, ContractionGrid& contr_grid, + Boundary const & left, + BoundaryMPSProduct const & left_mult_mps, + MPOTensor const & mpo, + DualIndex const & ket_basis, + Index const & right_i, Index const & out_left_i, + ProductBasis const & in_right_pb, ProductBasis const & out_left_pb) +{ + typedef typename MPOTensor::index_type index_type; + typedef typename MPOTensor::col_proxy col_proxy; + typedef typename SymmGroup::charge charge; + typedef std::size_t size_t; + col_proxy col_b2 = mpo.column(b2); + for (typename col_proxy::const_iterator col_it = col_b2.begin(); col_it != col_b2.end(); ++col_it) { + index_type b1 = col_it.index(); + block_matrix local; + block_matrix const & T = left_mult_mps.at(b1, local); + if(T.n_blocks() == 0) + continue; + MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); for (size_t oi = 0; oi < access.size(); ++oi) { - typename operator_selector::type const & W = access.op(oi); if(W.n_blocks() == 0) continue; - + typename operator_selector::type const & W = access.op(oi); + if(W.n_blocks() == 0) + continue; // charge deltas are constant for all blocks charge operator_delta = SymmGroup::fuse(W.basis().right_charge(0), -W.basis().left_charge(0)); charge T_delta = SymmGroup::fuse(T.basis().right_charge(0), -T.basis().left_charge(0)); charge total_delta = SymmGroup::fuse(operator_delta, -T_delta); - block_matrix& ret = contr_grid(b1,b2); parallel::guard group(contr_grid.where(b1,b2), contr_grid.granularity); parallel::scheduler_size_indexed scheduler(ret); - for (size_t r = 0; r < right_i.size(); ++r){ charge out_r_charge = right_i[r].first; - charge out_l_charge = SymmGroup::fuse(out_r_charge, total_delta); if(!out_left_i.has(out_l_charge)) continue; + charge out_l_charge = SymmGroup::fuse(out_r_charge, total_delta); + if(!out_left_i.has(out_l_charge)) + continue; size_t r_size = right_i[r].second; - size_t o = ret.find_block(out_l_charge, out_r_charge); for (size_t w_block = 0; w_block < W.n_blocks(); ++w_block){ charge phys_c1 = W.basis().left_charge(w_block); @@ -151,8 +139,9 @@ namespace contraction { charge in_r_charge = SymmGroup::fuse(out_r_charge, -phys_c1); charge in_l_charge = SymmGroup::fuse(in_r_charge, -T_delta); - size_t t_block = T.basis().position(in_l_charge, in_r_charge); if(t_block == T.basis().size()) continue; - + size_t t_block = T.basis().position(in_l_charge, in_r_charge); + if(t_block == T.basis().size()) + continue; size_t in_right_offset = in_right_pb(phys_c1, out_r_charge); size_t out_left_offset = out_left_pb(phys_c2, in_l_charge); size_t phys_s1 = W.basis().left_size(w_block); @@ -160,7 +149,6 @@ namespace contraction { Matrix const & wblock = W[w_block]; Matrix const & iblock = T[t_block]; Matrix & oblock = ret[o]; - parallel::guard proc(scheduler(o)); maquis::dmrg::detail::lb_tensor_mpo(oblock, iblock, wblock, out_left_offset, in_right_offset, @@ -168,48 +156,44 @@ namespace contraction { } } // right index block } // oi - } // b1 - } - - template - void rbtm_kernel_allocate(size_t b1, - block_matrix & ret, - Boundary const & right, - MPSBoundaryProduct const & right_mult_mps, - MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_right_basis, - Index const & left_i, - Index const & out_right_i) - { - typedef typename MPOTensor::index_type index_type; - typedef typename MPOTensor::row_proxy row_proxy; - - typedef typename SymmGroup::charge charge; - typedef std::size_t size_t; - - row_proxy row_b1 = mpo.row(b1); - for (typename row_proxy::const_iterator row_it = row_b1.begin(); row_it != row_b1.end(); ++row_it) { - index_type b2 = row_it.index(); - - DualIndex T_basis = detail::T_basis_right(right, right_mult_mps, mpo, ket_basis, ref_right_basis, b2); - if (T_basis.size() == 0) continue; - - MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); - + } // b1 +} + +template +void rbtm_kernel_allocate(size_t b1, block_matrix & ret, + Boundary const & right, + MPSBoundaryProduct const & right_mult_mps, + MPOTensor const & mpo, + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & left_i, Index const & out_right_i, + bool isHermitian) +{ + typedef typename MPOTensor::index_type index_type; + typedef typename MPOTensor::row_proxy row_proxy; + typedef typename SymmGroup::charge charge; + typedef std::size_t size_t; + row_proxy row_b1 = mpo.row(b1); + for (typename row_proxy::const_iterator row_it = row_b1.begin(); row_it != row_b1.end(); ++row_it) { + index_type b2 = row_it.index(); + DualIndex T_basis = detail::T_basis_right(right, right_mult_mps, mpo, ket_basis, bra_basis, b2, isHermitian); + if (T_basis.size() == 0) + continue; + MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); for (size_t oi = 0; oi < access.size(); ++oi) { - typename operator_selector::type const & W = access.op(oi); if(W.n_blocks() == 0) continue; - + typename operator_selector::type const & W = access.op(oi); + if(W.n_blocks() == 0) + continue; charge operator_delta = SymmGroup::fuse(W.basis().right_charge(0), -W.basis().left_charge(0)); charge T_delta = SymmGroup::fuse(T_basis.right_charge(0), -T_basis.left_charge(0)); charge total_delta = SymmGroup::fuse(operator_delta, -T_delta); - - for(size_t l = 0; l < left_i.size(); ++l){ + for(size_t l = 0; l < left_i.size(); ++l) { charge out_l_charge = left_i[l].first; - charge out_r_charge = SymmGroup::fuse(out_l_charge, -total_delta); if(!out_right_i.has(out_r_charge)) continue; + charge out_r_charge = SymmGroup::fuse(out_l_charge, -total_delta); + if(!out_right_i.has(out_r_charge)) + continue; size_t l_size = left_i[l].second; - if(ret.find_block(out_l_charge, out_r_charge) == ret.n_blocks()) + if(ret.find_block(out_l_charge, out_r_charge) == ret.n_blocks()) { #ifdef USE_AMBIENT // both versions should be fine for AMBIENT ret.resize_block(ret.insert_block(Matrix(1,1), out_l_charge, out_r_charge), @@ -217,64 +201,58 @@ namespace contraction { #else ret.insert_block(Matrix(l_size, out_right_i.size_of_block(out_r_charge)), out_l_charge, out_r_charge); #endif + } } } // oi - } // b2 - ret.index_sizes(); - } - - template - void rbtm_kernel_execute(size_t b1, - block_matrix & ret, - Boundary const & right, - MPSBoundaryProduct const & right_mult_mps, - MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & left_i, - Index const & out_right_i, - ProductBasis const & in_left_pb, - ProductBasis const & out_right_pb) - { - parallel::scheduler_size_indexed scheduler(ret); - - typedef typename MPOTensor::index_type index_type; - typedef typename MPOTensor::row_proxy row_proxy; - - typedef typename SymmGroup::charge charge; - typedef std::size_t size_t; - - row_proxy row_b1 = mpo.row(b1); - for (typename row_proxy::const_iterator row_it = row_b1.begin(); row_it != row_b1.end(); ++row_it) { - index_type b2 = row_it.index(); - - block_matrix const & T = right_mult_mps.at(b2); - if(T.n_blocks() == 0) continue; - - MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); - + } // b2 + ret.index_sizes(); +} + +template +void rbtm_kernel_execute(size_t b1, block_matrix & ret, + Boundary const & right, + MPSBoundaryProduct const & right_mult_mps, + MPOTensor const & mpo, + DualIndex const & ket_basis, + Index const & left_i, Index const & out_right_i, + ProductBasis const & in_left_pb, ProductBasis const & out_right_pb) +{ + parallel::scheduler_size_indexed scheduler(ret); + typedef typename MPOTensor::index_type index_type; + typedef typename MPOTensor::row_proxy row_proxy; + typedef typename SymmGroup::charge charge; + typedef std::size_t size_t; + row_proxy row_b1 = mpo.row(b1); + for (typename row_proxy::const_iterator row_it = row_b1.begin(); row_it != row_b1.end(); ++row_it) { + index_type b2 = row_it.index(); + block_matrix const & T = right_mult_mps.at(b2); + if(T.n_blocks() == 0) + continue; + MPOTensor_detail::term_descriptor access = mpo.at(b1,b2); for (size_t oi = 0; oi < access.size(); ++oi) { - typename operator_selector::type const & W = access.op(oi); if(W.n_blocks() == 0) continue; - + typename operator_selector::type const & W = access.op(oi); + if(W.n_blocks() == 0) + continue; // charge deltas are constant for all blocks charge operator_delta = SymmGroup::fuse(W.basis().right_charge(0), -W.basis().left_charge(0)); charge T_delta = SymmGroup::fuse(T.basis().right_charge(0), -T.basis().left_charge(0)); charge total_delta = SymmGroup::fuse(operator_delta, -T_delta); - for (size_t l = 0; l < left_i.size(); ++l){ charge out_l_charge = left_i[l].first; - charge out_r_charge = SymmGroup::fuse(out_l_charge, -total_delta); if(!out_right_i.has(out_r_charge)) continue; + charge out_r_charge = SymmGroup::fuse(out_l_charge, -total_delta); + if(!out_right_i.has(out_r_charge)) + continue; size_t l_size = left_i[l].second; size_t o = ret.find_block(out_l_charge, out_r_charge); - - for (size_t w_block = 0; w_block < W.n_blocks(); ++w_block){ + for (size_t w_block = 0; w_block < W.n_blocks(); ++w_block) { charge phys_c1 = W.basis().left_charge(w_block); charge phys_c2 = W.basis().right_charge(w_block); - charge in_l_charge = SymmGroup::fuse(out_l_charge, phys_c1); charge in_r_charge = SymmGroup::fuse(in_l_charge, T_delta); - size_t t_block = T.basis().position(in_l_charge, in_r_charge); if (t_block == T.basis().size()) continue; - + size_t t_block = T.basis().position(in_l_charge, in_r_charge); + if (t_block == T.basis().size()) + continue; size_t in_left_offset = in_left_pb(phys_c1, out_l_charge); size_t out_right_offset = out_right_pb(phys_c2, in_r_charge); size_t phys_s1 = W.basis().left_size(w_block); @@ -282,53 +260,44 @@ namespace contraction { const Matrix & wblock = W[w_block]; const Matrix & iblock = T[t_block]; Matrix & oblock = ret[o]; - parallel::guard proc(scheduler(o)); - maquis::dmrg::detail::rb_tensor_mpo(oblock, iblock, wblock, - out_right_offset, in_left_offset, - phys_s1, phys_s2, - l_size, T.basis().right_size(t_block), access.scale(oi)); + maquis::dmrg::detail::rb_tensor_mpo(oblock, iblock, wblock, out_right_offset, in_left_offset, + phys_s1, phys_s2, l_size, T.basis().right_size(t_block), access.scale(oi)); } } } // oi - } // b2 - right_mult_mps.free(b1); - } - - template - void lbtm_kernel(size_t b2, - ContractionGrid& contr_grid, - Boundary const & left, - BoundaryMPSProduct const & left_mult_mps, - MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_left_basis, - Index const & right_i, - Index const & out_left_i, - ProductBasis const & in_right_pb, - ProductBasis const & out_left_pb) - { - lbtm_kernel_allocate(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, ref_left_basis, right_i, out_left_i); - lbtm_kernel_execute(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, right_i, out_left_i, in_right_pb, out_left_pb); - } - - template - void rbtm_kernel(size_t b1, - block_matrix & ret, - Boundary const & right, - MPSBoundaryProduct const & right_mult_mps, - MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_right_basis, - Index const & left_i, - Index const & out_right_i, - ProductBasis const & in_left_pb, - ProductBasis const & out_right_pb) - { - rbtm_kernel_allocate(b1, ret, right, right_mult_mps, mpo, ket_basis, ref_right_basis, left_i, out_right_i); - rbtm_kernel_execute(b1, ret, right, right_mult_mps, mpo, ket_basis, left_i, out_right_i, in_left_pb, out_right_pb); - } - - } // namespace abelian + } // b2 + right_mult_mps.free(b1); +} + +template +void lbtm_kernel(size_t b2, ContractionGrid& contr_grid, + Boundary const & left, + BoundaryMPSProduct const & left_mult_mps, + MPOTensor const & mpo, + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & right_i, Index const & out_left_i, + ProductBasis const & in_right_pb, ProductBasis const & out_left_pb, + bool isHermitian=true) +{ + lbtm_kernel_allocate(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, bra_basis, right_i, out_left_i, isHermitian); + lbtm_kernel_execute(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, right_i, out_left_i, in_right_pb, out_left_pb); +} + +template +void rbtm_kernel(size_t b1, block_matrix & ret, + Boundary const & right, + MPSBoundaryProduct const & right_mult_mps, + MPOTensor const & mpo, + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & left_i, Index const & out_right_i, + ProductBasis const & in_left_pb, ProductBasis const & out_right_pb, + bool isHermitian=true) +{ + rbtm_kernel_allocate(b1, ret, right, right_mult_mps, mpo, ket_basis, bra_basis, left_i, out_right_i, isHermitian); + rbtm_kernel_execute(b1, ret, right, right_mult_mps, mpo, ket_basis, left_i, out_right_i, in_left_pb, out_right_pb); +} + +} // namespace abelian } // namespace contraction #endif diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/detail.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/detail.hpp index 7e9adf59a..424e6e8b3 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/detail.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/detail.hpp @@ -35,96 +35,144 @@ namespace contraction { namespace abelian { namespace detail { - template - DualIndex gemm_trim_left_basis(block_matrix const & A, - DualIndex const & B_basis, - Index const & ref_left_basis) - { - typedef typename DualIndex::const_iterator const_iterator; - - DualIndex ret; - - const_iterator B_begin = B_basis.begin(); - const_iterator B_end = B_basis.end(); - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - - // if (!B_basis.left_has(A.basis().left_charge(k))) continue; - if (!ref_left_basis.has(A.basis().left_charge(k))) continue; +/** + * @brief Returns the indices associated with the product of two [block_matrix] objects. + * + * Same as [gemm_trim_left], but does not do any "real" calculation, just returns + * the DualIndex object associated with the product of two block_matrix objects. + * Note that the second matrix is not passed as input, but is passed only as a + * DualIndex object. + * + * @param A First Matrix + * @param B_basis DualIndex associated with the second matrix. + * @param refBasis reference DualIndex used for trimming (as in [gemm_trim_left]) + * @return DualIndex Output DualIndex associated with A*B + */ +template +DualIndex gemm_trim_left_basis(block_matrix const & A, + DualIndex const & B_basis, + DualIndex const & refBasis) +{ + typedef typename DualIndex::const_iterator const_iterator; + DualIndex ret; + const_iterator B_begin = B_basis.begin(); + const_iterator B_end = B_basis.end(); + for (std::size_t k = 0; k < A.n_blocks(); ++k) { + if (!refBasis.left_has(A.basis().left_charge(k))) + continue; + typename SymmGroup::charge ar = A.basis().right_charge(k); + const_iterator it = B_basis.left_lower_bound(ar); + for ( ; it != B_end && it->lc == ar; ++it) + if (!ret.has(A.basis().left_charge(k), it->rc)) + ret.insert(typename DualIndex::value_type(A.basis().left_charge(k), it->rc, A.basis().left_size(k), it->rs)); + } + return ret; +} - typename SymmGroup::charge ar = A.basis().right_charge(k); - const_iterator it = B_basis.left_lower_bound(ar); - for ( ; it != B_end && it->lc == ar; ++it) - if (!ret.has(A.basis().left_charge(k), it->rc)) - ret.insert(typename DualIndex::value_type(A.basis().left_charge(k), it->rc, A.basis().left_size(k), it->rs)); +/** + * @brief Returns the indices associated with the product of two [block_matrix] objects. + * + * This is the right counterpart of [gemm_trim_left_basis] + * + * @param A First Matrix + * @param B_basis DualIndex associated with the second matrix. + * @param refBasis reference DualIndex used for right trimming (as in [gemm_trim_right]) + * @return DualIndex Output DualIndex associated with A*B + */ +template +DualIndex gemm_trim_right_basis(DualIndex const & A_basis, + block_matrix const & B, + DualIndex const & refBasis) +{ + typedef typename DualIndex::const_iterator const_iterator; + DualIndex ret; + const_iterator B_begin = B.basis().begin(); + const_iterator B_end = B.basis().end(); + Index A_right_basis(refBasis.size()); + for (size_t k = 0; k < refBasis.size(); ++k) + A_right_basis[k] = std::make_pair(refBasis.right_charge(k), refBasis.right_size(k)); + for (std::size_t k = 0; k < A_basis.size(); ++k) { + typename SymmGroup::charge ar = A_basis.right_charge(k); + const_iterator it = B.basis().left_lower_bound(ar); + for ( ; it != B_end && it->lc == ar; ++it) + { + if (!A_right_basis.has(it->rc)) + continue; // trim + if (!ret.has(A_basis.left_charge(k), it->rc)) + ret.insert(typename DualIndex::value_type(A_basis.left_charge(k), it->rc, A_basis.left_size(k), it->rs)); } - return ret; } - template - DualIndex gemm_trim_right_basis(DualIndex const & A_basis, - block_matrix const & B, - Index const & ref_right_basis) - { - typedef typename DualIndex::const_iterator const_iterator; - - DualIndex ret; - - const_iterator B_begin = B.basis().begin(); - const_iterator B_end = B.basis().end(); - Index A_right_basis(A_basis.size()); - for (size_t k = 0; k < A_basis.size(); ++k) - A_right_basis[k] = std::make_pair(A_basis.right_charge(k), A_basis.right_size(k)); - - for (std::size_t k = 0; k < A_basis.size(); ++k) { - - typename SymmGroup::charge ar = A_basis.right_charge(k); - const_iterator it = B.basis().left_lower_bound(ar); + return ret; +} - for ( ; it != B_end && it->lc == ar; ++it) - { - // if (!A_right_basis.has(it->rc)) continue; // trim - if (!ref_right_basis.has(it->rc)) continue; // trim - if (!ret.has(A_basis.left_charge(k), it->rc)) - ret.insert(typename DualIndex::value_type(A_basis.left_charge(k), it->rc, A_basis.left_size(k), it->rs)); - } +/** + * @brief Returns the index associated with a given b value of the BoundaryMPSProduct object. + * + * The first step of the contraction of a boundary with the MPS sitting on the next site (the + * same holds true also for the site_hamiltonian) is the creation of the BoundaryMPSProduct + * object, that stores the partial contraction of the boundary with the MPS. + * In some cases, to avoid storing large objects, QCMaquis postpones this contraction + * to a later step, specifically to the [Kernel] call. + * The Kernel call contracts the BoundaryMPSProduct with the MPO and, as a first step, + * allocates the memory that will accomodate the result of the Kernel(). + * This method is used to estimate the memory required for this allocation step. + * + * @param boundary Input (left) boundary object. + * @param mult_mps BoundaryMPSProduct object. + * @param mpo Input Matrix Product Operator + * @param mps_basis basis of the original mps + * @param refBasis reference basis for (left) trimming. + * @param b index of the BoundaryMPSProduct object + * @param isHermitian if true, activates the Hermitian treatment. + * @return DualIndex Index of the output block_matrix. + */ +template +DualIndex T_basis_left(Boundary const & boundary, + common::BoundaryMPSProduct const & mult_mps, + MPOTensor const & mpo, DualIndex const & mps_basis, + DualIndex const & refBasis, typename MPOTensor::index_type b, + bool isHermitian) +{ + if (mpo.num_row_non_zeros(b) == 1) { + if (mpo.herm_info.left_skip(b) && isHermitian) { + return gemm_trim_left_basis(conjugate(boundary[mpo.herm_info.left_conj(b)]), mps_basis, refBasis); + } + else { + return gemm_trim_left_basis(transpose(boundary[b]), mps_basis, refBasis); } - return ret; } - - - - template - DualIndex T_basis_left(Boundary const & boundary, - common::BoundaryMPSProduct const & mult_mps, - MPOTensor const & mpo, - DualIndex const & mps_basis, - Index const & ref_left_basis, - typename MPOTensor::index_type b) - { - if (mpo.num_row_non_zeros(b) == 1) - if (mpo.herm_info.left_skip(b)) - return gemm_trim_left_basis(conjugate(boundary[mpo.herm_info.left_conj(b)]), mps_basis, ref_left_basis); - else - return gemm_trim_left_basis(transpose(boundary[b]), mps_basis, ref_left_basis); - else - return mult_mps[b].basis(); + else { + return mult_mps[b].basis(); } - template - DualIndex T_basis_right(Boundary const & boundary, - common::MPSBoundaryProduct const & mult_mps, - MPOTensor const & mpo, - DualIndex const & mps_basis, - Index const & ref_right_basis, - typename MPOTensor::index_type b) - { - if (mpo.num_col_non_zeros(b) == 1) - if (mpo.herm_info.right_skip(b)) - return gemm_trim_right_basis(mps_basis, transpose(conjugate(boundary[mpo.herm_info.right_conj(b)])), ref_right_basis); - else - return gemm_trim_right_basis(mps_basis, boundary[b], ref_right_basis); +} + +/** + * @brief Right counterpart of [T_basis_left] + * @param boundary Input (right) boundary + * @param mult_mps MPSBoundaryProduct object + * @param mpo Input MPO + * @param mps_basis Basis of the MPS + * @param refBasis basis used as a reference to trim + * @param b index of the output MPSBoundaryProduct object. + * @param isHermitian if true, activates the Hermitian treatment. + * @return DualIndex Index storing the dimensions of the output block_matrix + */ +template +DualIndex T_basis_right(Boundary const & boundary, + common::MPSBoundaryProduct const & mult_mps, + MPOTensor const & mpo, + DualIndex const & mps_basis, DualIndex const & refBasis, + typename MPOTensor::index_type b, bool isHermitian) +{ + if (mpo.num_col_non_zeros(b) == 1) + if (mpo.herm_info.right_skip(b) && isHermitian) + return gemm_trim_right_basis(mps_basis, transpose(conjugate(boundary[mpo.herm_info.right_conj(b)])), refBasis); else - return mult_mps[b].basis(); - } + return gemm_trim_right_basis(mps_basis, boundary[b], refBasis); + else + return mult_mps[b].basis(); +} } } // namespace abelian diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/engine.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/engine.hpp index 38cdfd714..9bcac021e 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/engine.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/engine.hpp @@ -49,39 +49,32 @@ namespace contraction { struct lbtm_functor { - void operator()(size_t b2, - contraction::ContractionGrid& contr_grid, + void operator()(size_t b2, contraction::ContractionGrid& contr_grid, Boundary const & left, BoundaryMPSProduct const & left_mult_mps, MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_left_basis, - Index const & right_i, - Index const & out_left_i, - ProductBasis const & in_right_pb, - ProductBasis const & out_left_pb) + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & right_i, Index const & out_left_i, + ProductBasis const & in_right_pb, ProductBasis const & out_left_pb, + bool isHermitian) { - abelian::lbtm_kernel(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, ref_left_basis, - right_i, out_left_i, in_right_pb, out_left_pb); + abelian::lbtm_kernel(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, bra_basis, + right_i, out_left_i, in_right_pb, out_left_pb, isHermitian); } }; struct rbtm_functor { - void operator()(size_t b1, - block_matrix & ret, - Boundary const & right, + void operator()(size_t b1, block_matrix & ret, Boundary const & right, MPSBoundaryProduct const & right_mult_mps, MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_right_basis, - Index const & left_i, - Index const & out_right_i, - ProductBasis const & in_left_pb, - ProductBasis const & out_right_pb) + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & left_i, Index const & out_right_i, + ProductBasis const & in_left_pb, ProductBasis const & out_right_pb, + bool isHermitian) { - abelian::rbtm_kernel(b1, ret, right, right_mult_mps, mpo, ket_basis, ref_right_basis, - left_i, out_right_i, in_left_pb, out_right_pb); + abelian::rbtm_kernel(b1, ret, right, right_mult_mps, mpo, ket_basis, bra_basis, + left_i, out_right_i, in_left_pb, out_right_pb, isHermitian); } }; @@ -130,20 +123,22 @@ namespace contraction { overlap_mpo_left_step(MPSTensor const & bra_tensor, MPSTensor const & ket_tensor, Boundary const & left, - MPOTensor const & mpo) + MPOTensor const & mpo, + bool isHermitian=true) { return common::overlap_mpo_left_step - (bra_tensor, ket_tensor, left, mpo); + (bra_tensor, ket_tensor, left, mpo, isHermitian); } static Boundary overlap_mpo_right_step(MPSTensor const & bra_tensor, MPSTensor const & ket_tensor, Boundary const & right, - MPOTensor const & mpo) + MPOTensor const & mpo, + bool isHermitian=true) { return common::overlap_mpo_right_step - (bra_tensor, ket_tensor, right, mpo); + (bra_tensor, ket_tensor, right, mpo, isHermitian); } static std::pair, truncation_results> @@ -206,16 +201,27 @@ namespace contraction { site_hamil2(MPSTensor ket_tensor, Boundary const & left, Boundary const & right, - MPOTensor const & mpo); + MPOTensor const & mpo, + bool isHermitian=true); + + static MPSTensor + site_hamil2(MPSTensor ket_tensor, + MPSTensor const & bra_tensor, + Boundary const & left, + Boundary const & right, + MPOTensor const & mpo, + bool isHermitian=true); // Zero-site Hamiltonian static block_matrix zerosite_hamil2(block_matrix ket_tensor, Boundary const & left, - Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right); + Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian=true); static block_matrix zerosite_hamil2_kernel(block_matrix ket_tensor, Boundary const & left, - Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right); + Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian=true); }; diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/functors.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/functors.hpp index bed726ea9..bcde4a4d0 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/functors.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/functors.hpp @@ -35,69 +35,69 @@ namespace contraction { namespace abelian { - struct gemm_functor - { - template - void operator()(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - int spin = -1) - { - gemm(A,B,C); - } - }; +struct gemm_functor +{ + template + void operator()(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + int spin = -1) + { + gemm(A,B,C); + } +}; - struct gemm_trim_left_functor - { - template - void operator()(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - std::vector scales = std::vector()) - { - gemm_trim_left(A,B,C, B.left_basis()); - } +struct gemm_trim_left_functor +{ + template + void operator()(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + std::vector scales = std::vector()) + { + gemm_trim_left(A,B,C, B.left_basis()); + } - template - void operator()(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - Index const & ref_left_basis, - std::vector scales = std::vector()) - { - gemm_trim_left(A,B,C, ref_left_basis); - } + template + void operator()(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + Index const & ref_left_basis, + std::vector scales = std::vector()) + { + gemm_trim_left(A, B, C, ref_left_basis); + } - }; +}; - struct gemm_trim_right_functor - { - template - void operator()(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - std::vector scales = std::vector()) - { - gemm_trim_right(A,B,C, A.right_basis()); - } +struct gemm_trim_right_functor +{ + template + void operator()(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + std::vector scales = std::vector()) + { + gemm_trim_right(A,B,C, A.right_basis()); + } - template - void operator()(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - Index const & ref_right_basis, - std::vector scales = std::vector()) - { - gemm_trim_right(A,B,C, ref_right_basis); - } - }; + template + void operator()(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + Index const & ref_right_basis, + std::vector scales = std::vector()) + { + gemm_trim_right(A,B,C, ref_right_basis); + } +}; - struct Gemms - { - typedef gemm_functor gemm; - typedef gemm_trim_left_functor gemm_trim_left; - typedef gemm_trim_right_functor gemm_trim_right; - }; +struct Gemms +{ + typedef gemm_functor gemm; + typedef gemm_trim_left_functor gemm_trim_left; + typedef gemm_trim_right_functor gemm_trim_right; +}; } // namespace abelian } // namespace contraction diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/site_hamil.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/site_hamil.hpp index 96861254e..d5c7aafdf 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/site_hamil.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/site_hamil.hpp @@ -31,33 +31,47 @@ namespace contraction { - template - MPSTensor - Engine:: - site_hamil2(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo) - { - typedef typename SymmGroup::charge charge; - typedef typename MPOTensor::index_type index_type; +template +MPSTensor Engine:: + site_hamil2(MPSTensor ket_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian) +{ + return site_hamil2(ket_tensor, ket_tensor, left, right, mpo, isHermitian); +}; - contraction::common::BoundaryMPSProduct t(ket_tensor, left, mpo); - - Index const & physical_i = ket_tensor.site_dim(), - & left_i = ket_tensor.row_dim(); - Index right_i = ket_tensor.col_dim(), - out_left_i = physical_i * left_i; - common_subset(out_left_i, right_i); - ProductBasis out_left_pb(physical_i, left_i); - ProductBasis in_right_pb(physical_i, right_i, - boost::lambda::bind(static_cast(SymmGroup::fuse), - -boost::lambda::_1, boost::lambda::_2)); - - MPSTensor ret; - ret.phys_i = ket_tensor.site_dim(); ret.left_i = ket_tensor.row_dim(); ret.right_i = ket_tensor.col_dim(); - index_type loop_max = mpo.col_dim(); +template +MPSTensor +Engine:: +site_hamil2(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian) +{ + // Type declaration + using charge = typename SymmGroup::charge; + using index_type = std::size_t; + // + Index const & physical_i = ket_tensor.site_dim(); + Index const & left_i = bra_tensor.row_dim(); + bra_tensor.make_right_paired(); + Index indexForTrim = bra_tensor.data().left_basis(); + contraction::common::BoundaryMPSProduct t(ket_tensor, left, mpo, indexForTrim, isHermitian); + Index right_i = ket_tensor.col_dim(), + out_left_i = physical_i * left_i; + Index right_i_bra = bra_tensor.col_dim(); + common_subset(out_left_i, right_i); + ProductBasis out_left_pb(physical_i, left_i); + ProductBasis in_right_pb(physical_i, right_i, + boost::lambda::bind(static_cast(SymmGroup::fuse), + -boost::lambda::_1, boost::lambda::_2)); + // Prepares output tensor + MPSTensor ret; + ret.phys_i = bra_tensor.site_dim(); + ret.left_i = bra_tensor.row_dim(); + ret.right_i = bra_tensor.col_dim(); + auto loop_max = mpo.col_dim(); + bra_tensor.make_right_paired(); #ifdef USE_AMBIENT { block_matrix empty; @@ -67,7 +81,7 @@ namespace contraction { ContractionGrid contr_grid(mpo, left.aux_dim(), mpo.col_dim()); parallel_for(index_type b2, parallel::range(0,loop_max), { - abelian::lbtm_kernel(b2, contr_grid, left, t, mpo, ket_tensor.data().basis(), ket_tensor.data().left_basis(), right_i, out_left_i, in_right_pb, out_left_pb); + abelian::lbtm_kernel(b2, contr_grid, left, t, mpo, ket_tensor.data().basis(), bra_tensor.data().basis(), right_i, out_left_i, in_right_pb, out_left_pb); }); omp_for(index_type b2, parallel::range(0,loop_max), { contr_grid.multiply_column(b2, right[b2]); @@ -78,22 +92,23 @@ namespace contraction { swap(ret.data(), contr_grid.reduce()); parallel::sync(); #else - omp_for(index_type b2, parallel::range(0,loop_max), { - ContractionGrid contr_grid(mpo, 0, 0); - abelian::lbtm_kernel(b2, contr_grid, left, t, mpo, ket_tensor.data().basis(), ket_tensor.data().left_basis(), right_i, out_left_i, in_right_pb, out_left_pb); - block_matrix tmp; - if (mpo.herm_info.right_skip(b2)) - gemm(contr_grid(0,0), adjoint(right[mpo.herm_info.right_conj(b2)]), tmp); - else - gemm(contr_grid(0,0), right[b2], tmp); - contr_grid(0,0).clear(); - parallel_critical - for (std::size_t k = 0; k < tmp.n_blocks(); ++k) - ret.data().match_and_add_block(tmp[k], tmp.basis().left_charge(k), tmp.basis().right_charge(k)); - }); + omp_for(index_type b2, parallel::range(0,loop_max), { + ContractionGrid contr_grid(mpo, 0, 0); + abelian::lbtm_kernel(b2, contr_grid, left, t, mpo, ket_tensor.data().basis(), bra_tensor.data().basis(), right_i, out_left_i, in_right_pb, out_left_pb, + isHermitian); + block_matrix tmp; + if (mpo.herm_info.right_skip(b2) && isHermitian) + gemm(contr_grid(0,0), adjoint(right[mpo.herm_info.right_conj(b2)]), tmp); + else + gemm(contr_grid(0,0), right[b2], tmp); + contr_grid(0,0).clear(); + parallel_critical + for (std::size_t k = 0; k < tmp.n_blocks(); ++k) + ret.data().match_and_add_block(tmp[k], tmp.basis().left_charge(k), tmp.basis().right_charge(k)); + }); #endif - return ret; - } + return ret; +} } // namespace contraction diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/zero_site_hamil.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/zero_site_hamil.hpp index 786c20f14..42cc7b7f6 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/abelian/zero_site_hamil.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/abelian/zero_site_hamil.hpp @@ -36,25 +36,27 @@ template block_matrix Engine::zerosite_hamil2(block_matrix ket_tensor, Boundary const & left, Boundary const & right, - MPOTensor const & mpo_left, MPOTensor const & mpo_right) + MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian) { - return zerosite_hamil2_kernel(ket_tensor, left, right, mpo_left, mpo_right); + return zerosite_hamil2_kernel(ket_tensor, left, right, mpo_left, mpo_right, isHermitian); } template block_matrix Engine::zerosite_hamil2_kernel(block_matrix ket_bm, Boundary const & left, Boundary const & right, - MPOTensor const & mpo_left, MPOTensor const & mpo_right) + MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian) { using charge = typename SymmGroup::charge; using index_type = typename MPOTensor::index_type; - BoundaryMPSProduct t(ket_bm, left, mpo_right, false); + BoundaryMPSProduct t(ket_bm, left, mpo_right, isHermitian, false); block_matrix ret; index_type loop_max = mpo_right.row_dim(); omp_for(index_type b2, parallel::range(0,loop_max), { block_matrix tmp, local; - if (mpo_right.herm_info.left_skip(b2)) { + if (mpo_right.herm_info.left_skip(b2) && isHermitian) { gemm(t.at(b2, local), adjoint(right[mpo_left.herm_info.right_conj(b2)]), tmp); } else { diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/common/boundary_times_mps.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/common/boundary_times_mps.hpp index 4c488436b..abd06381a 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/common/boundary_times_mps.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/common/boundary_times_mps.hpp @@ -34,7 +34,6 @@ #include "dmrg/mp_tensors/reshapes.h" #include "dmrg/block_matrix/indexing.h" - namespace contraction { namespace common { @@ -91,83 +90,78 @@ namespace contraction { size_t b, bool left, bool forward) { } + /** + * @brief Class that manages the contraction of the left boundary with an MPS + * + * This is the first step to be performed for both: + * 1) the propagation of the boundaries. + * 2) the evaluation of the Site Hamiltonian. + * + * @tparam Matrix numeric matrix underlying the MPSTensor. + * @tparam OtherMatrix numeric martrix underlying the boundary. + * @tparam SymmGroup symmetry of the Hamiltonian encoded in the MPO. + * @tparam Gemm functor class with the Gemm operation. + */ template class BoundaryMPSProduct { public: // Types definition - typedef typename maquis::traits::scalar_type::type scalar_type; - typedef typename Matrix::value_type value_type; - typedef typename MPOTensor::index_type index_type; + using scalar_type = typename maquis::traits::scalar_type::type; + using value_type = typename Matrix::value_type; + using index_type = typename MPOTensor::index_type; + + /** + * @brief Constructor from a block_matrix (used in the zerosite_problem). + * @param bm reference block_matrix. + * @param left_ left boundary to be contracted with mps_ and mpo_ + * @param mpo_ reference MPOTensor + * @param ref_left_basis_ basis used as a reference + * @param correctConjugate_ if true, insert the phases required for the SU(2) case. + */ + BoundaryMPSProduct(block_matrix const & bm_, Boundary const & left_, + MPOTensor const & mpo_, Index const & ref_left_basis_, + bool isHermitian=true, bool correctConjugate_=true) + : bm(bm_), left(left_), mpo(mpo_), data_(left_.aux_dim()), ref_left_basis(ref_left_basis_), + correctConjugate(correctConjugate_), isHermitian_(isHermitian) + { + populateData(); + } - /** @brief Constructor from a mpstensor */ - BoundaryMPSProduct(MPSTensor const & mps_, - Boundary const & left_, - MPOTensor const & mpo_, - Index const & ref_left_basis_, - bool correctConjugate_=true) + /** + * @brief Constructor from an MPS + * Note that the change of pairing ensures that the MPS can be multiplied, from the left, + * to the left boundary. + */ + BoundaryMPSProduct(MPSTensor const & mps_, Boundary const & left_, + MPOTensor const & mpo_, Index const & ref_left_basis_, + bool isHermitian=true, bool correctConjugate_=true) : left(left_), mpo(mpo_), data_(left_.aux_dim()), ref_left_basis(ref_left_basis_), - correctConjugate(correctConjugate_) + correctConjugate(correctConjugate_), isHermitian_(isHermitian) { mps_.make_right_paired(); bm = mps_.data(); populateData(); } - /** @brief Constructor from a block_matrix */ - BoundaryMPSProduct(block_matrix const & bm_, - Boundary const & left_, - MPOTensor const & mpo_, - Index const & ref_left_basis_, - bool correctConjugate_=true) - : bm(bm_), left(left_), mpo(mpo_), data_(left_.aux_dim()), ref_left_basis(ref_left_basis_), - correctConjugate(correctConjugate_) + /** @brief Constructor from a block_matrix not taking a specific left basis */ + BoundaryMPSProduct(block_matrix const & bm_, Boundary const & left_, + MPOTensor const & mpo_, bool isHermitian=true, bool correctConjugate_=true) + : BoundaryMPSProduct(bm_, left_, mpo_, bm_.left_basis(), isHermitian, correctConjugate_) + {} + + /** @brief Constructor from a mps_tensor not taking a specific left basis */ + BoundaryMPSProduct(MPSTensor const & mps_, Boundary const & left_, + MPOTensor const & mpo_, bool isHermitian=true, bool correctConjugate_=true) + : left(left_), mpo(mpo_), data_(left_.aux_dim()), + correctConjugate(correctConjugate_), isHermitian_(isHermitian) { + mps_.make_right_paired(); + bm = mps_.data(); + ref_left_basis = mps_.data().left_basis(); populateData(); } - /** @brief Constructor not taking a specific left basis */ - BoundaryMPSProduct(MPSTensor const & mps_, - Boundary const & left_, - MPOTensor const & mpo_, - bool correctConjugate_=true) - : BoundaryMPSProduct(mps_, left_, mpo_, mps_.row_dim(), correctConjugate_) - {} - - /** @brief Constructor not taking a specific left basis */ - BoundaryMPSProduct(block_matrix const & bm_, - Boundary const & left_, - MPOTensor const & mpo_, - bool correctConjugate_=true) - : BoundaryMPSProduct(bm_, left_, mpo_, bm_.left_basis(), correctConjugate_) - {} - - /** @brief Populates the vector of block_matrix objects */ - void populateData() { - int loop_max = left.aux_dim(); - parallel::scheduler_permute scheduler(mpo.placement_l, parallel::groups_granularity); - // Loop over the elements - omp_for(int b1, parallel::range(0,loop_max), { - // exploit single use sparsity (delay multiplication until the object is used) - if (mpo.num_row_non_zeros(b1) == 1) - continue; - // exploit hermiticity if available - if (mpo.herm_info.left_skip(b1)) { - parallel::guard group(scheduler(b1), parallel::groups_granularity); - if (correctConjugate) { - std::vector scales = conjugate_phases(left[mpo.herm_info.left_conj(b1)], mpo, b1, true, false); - typename Gemm::gemm_trim_left()(conjugate(left[mpo.herm_info.left_conj(b1)]), bm, data_[b1], ref_left_basis, scales); - } - else { - typename Gemm::gemm_trim_left()(conjugate(left[mpo.herm_info.left_conj(b1)]), bm, data_[b1], ref_left_basis); - } - } - else { - typename Gemm::gemm_trim_left()(transpose(left[b1]), bm, data_[b1], ref_left_basis); - } - }); - } - /** @brief Gets the overall dimension of the BoundaryTimesMPS object */ std::size_t aux_dim() const { return data_.size(); @@ -184,11 +178,13 @@ namespace contraction { void multiply (index_type b1); block_matrix & operator[](std::size_t k) { return data_[k]; } + block_matrix const & operator[](std::size_t k) const { return data_[k]; } - block_matrix const & at(std::size_t k, block_matrix & storage) const { + block_matrix const & at(std::size_t k, block_matrix & storage) const + { if (mpo.num_row_non_zeros(k) == 1) { - if (mpo.herm_info.left_skip(k)) { + if (mpo.herm_info.left_skip(k) && isHermitian_) { if (correctConjugate) { std::vector scales = conjugate_phases(left[mpo.herm_info.left_conj(k)], mpo, k, true, false); typename Gemm::gemm_trim_left()(conjugate(left[mpo.herm_info.left_conj(k)]), bm, storage, ref_left_basis, scales); @@ -207,12 +203,41 @@ namespace contraction { } private: + /** + * @brief Loads the contraction of the MPS with the left boundary. + */ + void populateData() { + int loop_max = left.aux_dim(); + parallel::scheduler_permute scheduler(mpo.placement_l, parallel::groups_granularity); + // Loop over the elements + omp_for(int b1, parallel::range(0,loop_max), { + // exploit single use sparsity (delay multiplication until the object is used) + if (mpo.num_row_non_zeros(b1) == 1) + continue; + // exploit hermiticity if available + if (mpo.herm_info.left_skip(b1) && isHermitian_) { + parallel::guard group(scheduler(b1), parallel::groups_granularity); + if (correctConjugate) { + std::vector scales = conjugate_phases(left[mpo.herm_info.left_conj(b1)], mpo, b1, true, false); + typename Gemm::gemm_trim_left()(conjugate(left[mpo.herm_info.left_conj(b1)]), bm, data_[b1], ref_left_basis, scales); + } + else { + typename Gemm::gemm_trim_left()(conjugate(left[mpo.herm_info.left_conj(b1)]), bm, data_[b1], ref_left_basis); + } + } + else { + typename Gemm::gemm_trim_left()(transpose(left[b1]), bm, data_[b1], ref_left_basis); + } + }); + } + + // Class members std::vector > data_; block_matrix bm; Boundary const & left; MPOTensor const & mpo; Index ref_left_basis; - bool correctConjugate; + bool correctConjugate, isHermitian_; }; @@ -233,9 +258,9 @@ namespace contraction { /** @brief Constructor from a MPS tensor */ MPSBoundaryProduct(MPSTensor const & mps_, Boundary const & right_, MPOTensor const & mpo_, Index const& ref_right_basis_, - bool correctConjugate_=true) + bool isHermitian=true, bool correctConjugate_=true) : right(right_), mpo(mpo_), data_(right_.aux_dim()), pop_(right_.aux_dim(), 0), - ref_right_basis(ref_right_basis_), correctConjugate(correctConjugate_) + ref_right_basis(ref_right_basis_), correctConjugate(correctConjugate_), isHermitian_(isHermitian) { mps_.make_left_paired(); bm = mps_.data(); @@ -245,23 +270,23 @@ namespace contraction { /** @brief Constructor from a block_matrix */ MPSBoundaryProduct(block_matrix const & bm_, Boundary const & right_, MPOTensor const & mpo_, Index const& ref_right_basis_, - bool correctConjugate_=true) + bool isHermitian=true, bool correctConjugate_=true) : right(right_), mpo(mpo_), data_(right_.aux_dim()), pop_(right_.aux_dim(), 0), - ref_right_basis(ref_right_basis_), bm(bm_), correctConjugate(correctConjugate_) + ref_right_basis(ref_right_basis_), bm(bm_), isHermitian_(isHermitian), correctConjugate(correctConjugate_) { populateData(); } /** @brief Constructor without index */ MPSBoundaryProduct(MPSTensor const & mps_, Boundary const & right_, - MPOTensor const & mpo_, bool correctConjugate_=true) - : MPSBoundaryProduct(mps_, right_, mpo_, mps_.col_dim(), correctConjugate_) + MPOTensor const & mpo_, bool isHermitian=true, bool correctConjugate_=true) + : MPSBoundaryProduct(mps_, right_, mpo_, mps_.row_dim(), isHermitian, correctConjugate_) {} /** @brief Constructor without index */ MPSBoundaryProduct(block_matrix const & bm_, Boundary const & right_, - MPOTensor const & mpo_, bool correctConjugate_=true) - : MPSBoundaryProduct(bm_, right_, mpo_, bm_.right_basis(), correctConjugate_) + MPOTensor const & mpo_, bool isHermitian=true, bool correctConjugate_=true) + : MPSBoundaryProduct(bm_, right_, mpo_, bm_.left_basis(), isHermitian, correctConjugate_) {} /** @brief Core method called by the constructor */ @@ -274,7 +299,7 @@ namespace contraction { if (mpo.num_col_non_zeros(b2) == 1) continue; // exploit hermiticity if available - if (mpo.herm_info.right_skip(b2)) + if (mpo.herm_info.right_skip(b2) && isHermitian_) { parallel::guard group(scheduler(b2), parallel::groups_granularity); block_matrix::type, SymmGroup> trv = adjoint(right[mpo.herm_info.right_conj(b2)]); @@ -314,17 +339,17 @@ namespace contraction { { if (mpo.num_col_non_zeros(k) == 1) { - if (mpo.herm_info.right_skip(k)) + if (mpo.herm_info.right_skip(k) && isHermitian_) { //parallel::guard group(scheduler(b2), parallel::groups_granularity); block_matrix::type, SymmGroup> trv = adjoint(right[mpo.herm_info.right_conj(k)]); //return typename Gemm::gemm_trim_right()(mps.data(), trv); - return SU2::gemm_trim_right_pretend(bm, trv); + return SU2::gemm_trim_right_pretend(bm.basis(), trv, ref_right_basis); } else { //parallel::guard group(scheduler(b2), parallel::groups_granularity); //return typename Gemm::gemm_trim_right_pretend()(mps.data(), right[k]); - return SU2::gemm_trim_right_pretend(bm, right[k]); + return SU2::gemm_trim_right_pretend(bm.basis(), right[k], ref_right_basis); } } else @@ -338,7 +363,7 @@ namespace contraction { { if (!pop_[k]) { - if (mpo.herm_info.right_skip(k)) + if (mpo.herm_info.right_skip(k) && isHermitian_) { //parallel::guard group(scheduler(b2), parallel::groups_granularity); //typename Gemm::gemm_trim_right()(mps.data(), transpose(right[mpo.herm_info.right_conj(k)]), storage); @@ -382,7 +407,7 @@ namespace contraction { private: mutable std::vector > data_; mutable std::vector pop_; - bool correctConjugate; + bool correctConjugate, isHermitian_; block_matrix bm; Boundary const & right; MPOTensor const & mpo; diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/common/move_boundary.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/common/move_boundary.hpp index 53397f70a..59c87e7e2 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/common/move_boundary.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/common/move_boundary.hpp @@ -48,13 +48,13 @@ overlap_left_step(MPSTensor const & bra_tensor, if (localop != NULL) throw std::runtime_error("Not implemented!"); assert(ket_tensor.phys_i == bra_tensor.phys_i); - bra_tensor.make_left_paired(); block_matrix t1; block_matrix t3; ket_tensor.make_right_paired(); typename Gemm::gemm()(left, ket_tensor.data(), t1); reshape_right_to_left_new(ket_tensor.site_dim(), bra_tensor.row_dim(), ket_tensor.col_dim(), t1, t3); + bra_tensor.make_left_paired(); typename Gemm::gemm()(transpose(conjugate(bra_tensor.data())), t3, t1); return t1; // original: @@ -73,12 +73,12 @@ overlap_right_step(MPSTensor const & bra_tensor, if (localop != NULL) throw std::runtime_error("Not implemented!"); assert(ket_tensor.phys_i == bra_tensor.phys_i); - bra_tensor.make_right_paired(); ket_tensor.make_left_paired(); block_matrix t1; block_matrix t3; typename Gemm::gemm()(ket_tensor.data(), transpose(right), t1); reshape_left_to_right_new(ket_tensor.site_dim(), ket_tensor.row_dim(), bra_tensor.col_dim(), t1, t3); + bra_tensor.make_right_paired(); typename Gemm::gemm()(conjugate(bra_tensor.data()), transpose(t3), t1); return t1; } @@ -97,9 +97,9 @@ left_boundary_tensor_mpo(MPSTensor mps, if (in_low == NULL) in_low = &mps.row_dim(); //std::vector > t - BoundaryMPSProduct t(mps, left, mpo); Index physical_i = mps.site_dim(), left_i = *in_low, right_i = mps.col_dim(), out_left_i = physical_i * left_i; + BoundaryMPSProduct t(mps, left, mpo, left_i); ProductBasis out_left_pb(physical_i, left_i); ProductBasis in_right_pb(physical_i, right_i, boost::lambda::bind(static_cast(SymmGroup::fuse), @@ -109,7 +109,8 @@ left_boundary_tensor_mpo(MPSTensor mps, ret.resize(mpo.col_dim()); omp_for(index_type b2, parallel::range(0,loop_max), { ContractionGrid contr_grid(mpo, 0, 0); - Kernel()(b2, contr_grid, left, t, mpo, mps.data().basis(), mps.data().left_basis(), right_i, out_left_i, in_right_pb, out_left_pb); + Kernel()(b2, contr_grid, left, t, mpo, mps.data().basis(), mps.data().basis(), + right_i, out_left_i, in_right_pb, out_left_pb, true); swap(ret[b2], contr_grid(0,0)); }); return ret; @@ -139,32 +140,35 @@ right_boundary_tensor_mpo(MPSTensor mps, index_type loop_max = mpo.row_dim(); omp_for(index_type b1, parallel::range(0,loop_max), { parallel::guard group(scheduler(b1), parallel::groups_granularity); - Kernel()(b1, ret[b1], right, t, mpo, mps.data().basis(), mps.data().right_basis(), left_i, out_right_i, in_left_pb, out_right_pb); + Kernel()(b1, ret[b1], right, t, mpo, mps.data().basis(), mps.data().basis(), + left_i, out_right_i, in_left_pb, out_right_pb, true); }); return ret; } template static Boundary -overlap_mpo_left_step(MPSTensor const & bra_tensor, - MPSTensor const & ket_tensor, - Boundary const & left, - MPOTensor const & mpo) +overlap_mpo_left_step(MPSTensor const & bra_tensor, MPSTensor const & ket_tensor, + Boundary const & left, MPOTensor const & mpo, + bool isHermitian=true) { typedef typename SymmGroup::charge charge; typedef typename MPOTensor::index_type index_type; - Index const & left_i = bra_tensor.row_dim(); + bra_tensor.make_right_paired(); + Index braBasis = bra_tensor.data().left_basis(); MPSTensor ket_cpy = ket_tensor; - BoundaryMPSProduct t(ket_cpy, left, mpo, left_i); + BoundaryMPSProduct t(ket_cpy, left, mpo, braBasis, isHermitian); + Index const & left_i = bra_tensor.row_dim(); Index right_i = ket_tensor.col_dim(); Index bra_right_i = bra_tensor.col_dim(); Index out_left_i = bra_tensor.site_dim() * left_i; common_subset(out_left_i, bra_right_i); - ProductBasis out_left_pb(ket_tensor.site_dim(), left_i); + ProductBasis out_left_pb(bra_tensor.site_dim(), left_i); ProductBasis in_right_pb(ket_tensor.site_dim(), right_i, boost::lambda::bind(static_cast(SymmGroup::fuse), -boost::lambda::_1, boost::lambda::_2)); index_type loop_max = mpo.col_dim(); + DualIndex bra_basis = bra_tensor.data().basis(); bra_tensor.make_left_paired(); block_matrix bra_conj = conjugate(bra_tensor.data()); DualIndex ket_basis_transpose = ket_cpy.data().basis(); @@ -175,10 +179,10 @@ overlap_mpo_left_step(MPSTensor const & bra_tensor, Boundary ret; ret.resize(loop_max); omp_for(index_type b2, parallel::range(0,loop_max), { - if (mpo.herm_info.right_skip(b2)) continue; + if (mpo.herm_info.right_skip(b2) && isHermitian) + continue; ContractionGrid contr_grid(mpo, 0, 0); - block_matrix tmp; - Kernel()(b2, contr_grid, left, t, mpo, ket_basis_transpose, left_i, right_i, out_left_i, in_right_pb, out_left_pb); + Kernel()(b2, contr_grid, left, t, mpo, ket_basis_transpose, bra_basis, right_i, out_left_i, in_right_pb, out_left_pb, isHermitian); typename Gemm::gemm()(transpose(contr_grid(0,0)), bra_conj, ret[b2], MPOTensor_detail::get_spin(mpo, b2, false)); }); /* @@ -205,10 +209,9 @@ overlap_mpo_left_step(MPSTensor const & bra_tensor, template static Boundary -overlap_mpo_right_step(MPSTensor const & bra_tensor, - MPSTensor const & ket_tensor, - Boundary const & right, - MPOTensor const & mpo) +overlap_mpo_right_step(MPSTensor const & bra_tensor, MPSTensor const & ket_tensor, + Boundary const & right, MPOTensor const & mpo, + bool isHermitian=true) { typedef typename SymmGroup::charge charge; typedef typename MPOTensor::index_type index_type; @@ -216,10 +219,12 @@ overlap_mpo_right_step(MPSTensor const & bra_tensor, Index const & physical_i = ket_tensor.site_dim(), right_i = bra_tensor.col_dim(); MPSTensor ket_cpy = ket_tensor; - contraction::common::MPSBoundaryProduct t(ket_cpy, right, mpo, right_i); Index left_i = ket_tensor.row_dim(), out_right_i = adjoin(physical_i) * right_i, bra_left_i = bra_tensor.row_dim(); + bra_tensor.make_left_paired(); + Index indexForTrim = bra_tensor.data().right_basis(); + contraction::common::MPSBoundaryProduct t(ket_cpy, right, mpo, indexForTrim, isHermitian); common_subset(out_right_i, bra_left_i); ProductBasis in_left_pb(physical_i, left_i); ProductBasis out_right_pb(physical_i, right_i, @@ -229,11 +234,14 @@ overlap_mpo_right_step(MPSTensor const & bra_tensor, ret.resize(mpo.row_dim()); //ket_tensor.make_right_paired(); index_type loop_max = mpo.row_dim(); + bra_tensor.make_left_paired(); + DualIndex bra_basis = bra_tensor.data().basis(); bra_tensor.make_right_paired(); block_matrix bra_conj = conjugate(bra_tensor.data()); omp_for(index_type b1, parallel::range(0,loop_max), { - if (mpo.herm_info.left_skip(b1)) continue; - Kernel()(b1, ret[b1], right, t, mpo, ket_cpy.data().basis(), right_i, left_i, out_right_i, in_left_pb, out_right_pb); + if (mpo.herm_info.left_skip(b1) && isHermitian) + continue; + Kernel()(b1, ret[b1], right, t, mpo, ket_cpy.data().basis(), bra_basis, left_i, out_right_i, in_left_pb, out_right_pb, isHermitian); block_matrix tmp; typename Gemm::gemm()(ret[b1], transpose(bra_conj), tmp, MPOTensor_detail::get_spin(mpo, b1, true)); //gemm(ret[b1], transpose(bra_conj), tmp, parallel::scheduler_size_indexed(ret[b1])); @@ -288,7 +296,8 @@ generate_left_mpo_basis(MPSTensor const & bra_tensor, // Br if (mpo.herm_info.right_skip(b2)) continue; ContractionGrid contr_grid(mpo, 0, 0); - Kernel()(b2, contr_grid, left, t, mpo, ket_basis_transpose, left_i, right_i, out_left_i, in_right_pb, out_left_pb); + Kernel()(b2, contr_grid, left, t, mpo, ket_basis_transpose, ket_basis_transpose, right_i, out_left_i, + in_right_pb, out_left_pb, true); // Final contraction with the MPS ret[b2] = contr_grid(0,0); }); @@ -329,7 +338,7 @@ generate_right_mpo_basis(MPSTensor const & bra_tensor, MPSTen omp_for(index_type b1, parallel::range(0,loop_max), { if (mpo.herm_info.left_skip(b1)) continue; - Kernel()(b1, ret[b1], right, t, mpo, ket_cpy.data().basis(), right_i, left_i, out_right_i, in_left_pb, out_right_pb); + Kernel()(b1, ret[b1], right, t, mpo, ket_cpy.data().basis(), ket_cpy.data().basis(), left_i, out_right_i, in_left_pb, out_right_pb, true); }); return ret; } diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/apply_op.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/apply_op.hpp index 906357959..8761092d5 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/apply_op.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/apply_op.hpp @@ -93,7 +93,8 @@ namespace SU2 { charge out_l_charge = SymmGroup::fuse(lc, phys_out); if (!::SU2::triangle(SymmGroup::spin(out_r_charge), ap, SymmGroup::spin(out_l_charge))) continue; - if (!right_i.has(out_l_charge)) continue; // can also probe out_left_i, but right_i has the same charges + if (!out_left_i.has(out_l_charge)) + continue; size_t r_size = right_i[rb].second; @@ -182,7 +183,7 @@ namespace SU2 { charge out_r_charge = SymmGroup::fuse(rc, -phys_out); if (!::SU2::triangle(SymmGroup::spin(out_l_charge), a, SymmGroup::spin(out_r_charge))) continue; - if (!left_i.has(out_r_charge)) continue; + if (!out_right_i.has(out_r_charge)) continue; size_t l_size = left_i[lb].second; @@ -318,4 +319,4 @@ namespace SU2 { } // namespace SU2 } // namespace contraction -#endif \ No newline at end of file +#endif diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/engine.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/engine.hpp index fbefcf42c..170357bbe 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/engine.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/engine.hpp @@ -49,37 +49,33 @@ namespace contraction { { struct lbtm_functor { - void operator()(size_t b2, - contraction::ContractionGrid& contr_grid, + void operator()(size_t b2, contraction::ContractionGrid& contr_grid, Boundary const & left, BoundaryMPSProduct const & left_mult_mps, MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_left_basis, - Index const & right_i, - Index const & out_left_i, - ProductBasis const & in_right_pb, - ProductBasis const & out_left_pb) + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & right_i, Index const & out_left_i, + ProductBasis const & in_right_pb, ProductBasis const & out_left_pb, + bool isHermitian=true) { - return SU2::lbtm_kernel(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, right_i, out_left_i, in_right_pb, out_left_pb); + return SU2::lbtm_kernel(b2, contr_grid, left, left_mult_mps, mpo, ket_basis, right_i, + out_left_i, in_right_pb, out_left_pb); } }; struct rbtm_functor { - void operator()(size_t b1, - block_matrix & ret, + void operator()(size_t b1, block_matrix & ret, Boundary const & right, MPSBoundaryProduct const & right_mult_mps, MPOTensor const & mpo, - DualIndex const & ket_basis, - Index const & ref_right_basis, - Index const & left_i, - Index const & out_right_i, - ProductBasis const & in_left_pb, - ProductBasis const & out_right_pb) + DualIndex const & ket_basis, DualIndex const & bra_basis, + Index const & left_i, Index const & out_right_i, + ProductBasis const & in_left_pb, ProductBasis const & out_right_pb, + bool isHermitian=true) { - return SU2::rbtm_kernel(b1, ret, right, right_mult_mps, mpo, ket_basis, left_i, out_right_i, in_left_pb, out_right_pb); + return SU2::rbtm_kernel(b1, ret, right, right_mult_mps, mpo, ket_basis, left_i, out_right_i, + in_left_pb, out_right_pb); } }; @@ -129,20 +125,22 @@ namespace contraction { overlap_mpo_left_step(MPSTensor const & bra_tensor, MPSTensor const & ket_tensor, Boundary const & left, - MPOTensor const & mpo) + MPOTensor const & mpo, + bool isHermitian=true) { return common::overlap_mpo_left_step - (bra_tensor, ket_tensor, left, mpo); + (bra_tensor, ket_tensor, left, mpo, isHermitian); } static Boundary overlap_mpo_right_step(MPSTensor const & bra_tensor, MPSTensor const & ket_tensor, Boundary const & right, - MPOTensor const & mpo) + MPOTensor const & mpo, + bool isHermitian=true) { return common::overlap_mpo_right_step - (bra_tensor, ket_tensor, right, mpo); + (bra_tensor, ket_tensor, right, mpo, isHermitian); } // Single-site prediction @@ -200,19 +198,27 @@ namespace contraction { static MPSTensor site_hamil2(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo); + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, + bool isHermitian=true); + + static MPSTensor + site_hamil2(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, + bool isHermitian=true); static block_matrix zerosite_hamil2(block_matrix bra_tensor, block_matrix ket_tensor, Boundary const & left, Boundary const & right, - MPOTensor const & mpo_left, MPOTensor const & mpo_right); + MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian=true); static block_matrix zerosite_hamil2(block_matrix ket_tensor, Boundary const & left, Boundary const & right, MPOTensor const & mpo_left, - MPOTensor const & mpo_right); + MPOTensor const & mpo_right, + bool isHermitian=true); }; } // namespace contraction diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/functors.h b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/functors.h index 0364d7408..b5f9cbd1a 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/functors.h +++ b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/functors.h @@ -54,7 +54,7 @@ namespace SU2 { block_matrix & C, std::vector scales = std::vector()) { - SU2::gemm_trim_left(A,B,C, scales); + SU2::gemm_trim_left(A, B, C, scales); } template @@ -64,7 +64,7 @@ namespace SU2 { Index const & ref_left_basis, std::vector scales = std::vector()) { - SU2::gemm_trim_left(A,B,C, scales); + SU2::gemm_trim_left(A, B, C, ref_left_basis, scales); } }; @@ -86,7 +86,7 @@ namespace SU2 { Index const & ref_right_basis, std::vector scales = std::vector()) { - SU2::gemm_trim_right(A,B,C, scales); + SU2::gemm_trim_right(A, B, C, ref_right_basis, scales); } }; diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/gemm.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/gemm.hpp index b1adc0431..39d5ae2e9 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/gemm.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/gemm.hpp @@ -29,216 +29,200 @@ #define CONTRACTIONS_SU2_GEMM_HPP #include "dmrg/block_matrix/block_matrix.h" +#include "dmrg/block_matrix/indexing.h" namespace SU2 { - template - T conjugate_correction(typename SymmGroup::charge lc, typename SymmGroup::charge rc, typename SymmGroup::subcharge tensor_spin) - { - assert( SymmGroup::spin(lc) >= 0); - assert( SymmGroup::spin(rc) >= 0); - typename SymmGroup::subcharge S = std::min(SymmGroup::spin(rc), SymmGroup::spin(lc)); - typename SymmGroup::subcharge spin_diff = SymmGroup::spin(rc) - SymmGroup::spin(lc); - T ret = 0.; - if (tensor_spin == 0) { +/** @brief Returns the factor correcting the MPO-MPS network for the Hermitian conjugate case */ +template +T conjugate_correction(typename SymmGroup::charge lc, typename SymmGroup::charge rc, typename SymmGroup::subcharge tensor_spin) +{ + assert( SymmGroup::spin(lc) >= 0); + assert( SymmGroup::spin(rc) >= 0); + typename SymmGroup::subcharge S = std::min(SymmGroup::spin(rc), SymmGroup::spin(lc)); + typename SymmGroup::subcharge spin_diff = SymmGroup::spin(rc) - SymmGroup::spin(lc); + T ret = 0.; + if (tensor_spin == 0) { + ret = T(1.); + } + else if (tensor_spin == 1) { + if (spin_diff > 0) + ret = -T( sqrt((S + 1.)/(S + 2.)) ); + else if (spin_diff < 0) + ret = T( sqrt((S + 2.)/(S + 1.)) ); + } + else if (tensor_spin == 2) { + if (spin_diff > 0) + ret = -T( sqrt( (S + 1.) / (S + 3.)) ); + else if (spin_diff < 0) + ret = -T( sqrt((S + 3.) / (S + 1.)) ); + else ret = T(1.); - } - else if (tensor_spin == 1) { - if (spin_diff > 0) - ret = -T( sqrt((S + 1.)/(S + 2.)) ); - - else if (spin_diff < 0) - ret = T( sqrt((S + 2.)/(S + 1.)) ); - } - else if (tensor_spin == 2) { - if (spin_diff > 0) - ret = -T( sqrt( (S + 1.) / (S + 3.)) ); - else if (spin_diff < 0) - ret = -T( sqrt((S + 3.) / (S + 1.)) ); - else - ret = T(1.); - } - else { - throw std::runtime_error("hermitian conjugate for reduced tensor operators only implemented up to rank 1"); - } - return ret; } - - template - void gemm(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - int spin) - { - typedef typename SymmGroup::charge charge; - typedef typename DualIndex::const_iterator const_iterator; - typedef typename Matrix3::value_type value_type; - - C.clear(); - assert(B.basis().is_sorted()); - - const_iterator B_begin = B.basis().begin(); - const_iterator B_end = B.basis().end(); - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - - charge ar = A.basis().right_charge(k); - const_iterator it = B.basis().left_lower_bound(ar); - - for ( ; it != B_end && it->lc == ar; ++it) - { - std::size_t matched_block = std::distance(B_begin, it); - if (!(spin == -1) && !::SU2::triangle(SymmGroup::spin(A.basis().left_charge(k)), spin, SymmGroup::spin(it->rc))) - continue; - - std::size_t c_block = C.find_block(A.basis().left_charge(k), it->rc); - if (c_block == C.n_blocks()) - c_block = C.insert_block(Matrix3(num_rows(A[k]), it->rs), A.basis().left_charge(k), it->rc); - - boost::numeric::bindings::blas::gemm(value_type(1), A[k], B[matched_block], value_type(1), C[c_block]); - } - } + else { + throw std::runtime_error("hermitian conjugate for reduced tensor operators only implemented up to rank 1"); } - - template - void gemm_trim_left(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - std::vector conj_scales = std::vector()) - { - typedef typename SymmGroup::charge charge; - typedef typename DualIndex::const_iterator const_iterator; - typedef typename Matrix3::value_type value_type; - - if (conj_scales.size() != A.n_blocks()) - conj_scales = std::vector(A.n_blocks(), 1.); - - C.clear(); - assert(B.basis().is_sorted()); - - const_iterator B_begin = B.basis().begin(); - const_iterator B_end = B.basis().end(); - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - - //assert(B.basis().left_has(A.basis().left_charge(k))); - if (!B.basis().left_has(A.basis().left_charge(k))) continue; - - charge ar = A.basis().right_charge(k); - const_iterator it = B.basis().left_lower_bound(ar); - - for ( ; it != B_end && it->lc == ar; ++it) - { - std::size_t matched_block = std::distance(B_begin, it); - - std::size_t c_block = C.find_block(A.basis().left_charge(k), it->rc); - if (c_block == C.n_blocks()) - c_block = C.insert_block(Matrix3(num_rows(A[k]), it->rs), A.basis().left_charge(k), it->rc); - - boost::numeric::bindings::blas::gemm(conj_scales[k], A[k], B[matched_block], value_type(1), C[c_block]); - } + return ret; +} +/** @brief block_matrix-block_matrix multiplication */ +template +void gemm(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + int spin) +{ + typedef typename SymmGroup::charge charge; + typedef typename DualIndex::const_iterator const_iterator; + typedef typename Matrix3::value_type value_type; + C.clear(); + assert(B.basis().is_sorted()); + const_iterator B_begin = B.basis().begin(); + const_iterator B_end = B.basis().end(); + for (std::size_t k = 0; k < A.n_blocks(); ++k) { + charge ar = A.basis().right_charge(k); + const_iterator it = B.basis().left_lower_bound(ar); + for ( ; it != B_end && it->lc == ar; ++it) + { + std::size_t matched_block = std::distance(B_begin, it); + if (!(spin == -1) && !::SU2::triangle(SymmGroup::spin(A.basis().left_charge(k)), spin, SymmGroup::spin(it->rc))) + continue; + std::size_t c_block = C.find_block(A.basis().left_charge(k), it->rc); + if (c_block == C.n_blocks()) + c_block = C.insert_block(Matrix3(num_rows(A[k]), it->rs), A.basis().left_charge(k), it->rc); + boost::numeric::bindings::blas::gemm(value_type(1), A[k], B[matched_block], value_type(1), C[c_block]); } } +} - template - DualIndex gemm_trim_right_pretend(block_matrix const & A, - block_matrix const & B) - { - typedef typename SymmGroup::charge charge; - typedef typename DualIndex::const_iterator const_iterator; - - assert(B.basis().is_sorted()); - DualIndex ret; - - const_iterator B_end = B.basis().end(); - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - - charge ar = A.basis().right_charge(k); - const_iterator it = B.basis().left_lower_bound(ar); - - for ( ; it != B_end && it->lc == ar; ++it) - { - if (!A.basis().left_has(it->rc)) continue; - - charge lc = A.basis().left_charge(k); - charge rc = it->rc; - - if (!ret.has(lc, rc)) - ret.insert(typename DualIndex::value_type(lc, rc, num_rows(A[k]), it->rs)); - } +/** @brief block_matrix multipication with left trimming (see abelian version of [gemm_trim_left]) */ +template +void gemm_trim_left(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + Index const & refIndex, + std::vector conj_scales = std::vector()) +{ + using charge = typename SymmGroup::charge; + using const_iterator = typename DualIndex::const_iterator; + using value_type = typename Matrix3::value_type; + + if (conj_scales.size() != A.n_blocks()) + conj_scales = std::vector(A.n_blocks(), 1.); + + C.clear(); + assert(B.basis().is_sorted()); + + const_iterator B_begin = B.basis().begin(); + const_iterator B_end = B.basis().end(); + for (std::size_t k = 0; k < A.n_blocks(); ++k) { + + //assert(B.basis().left_has(A.basis().left_charge(k))); + if (!refIndex.has(A.basis().left_charge(k))) + continue; + + charge ar = A.basis().right_charge(k); + const_iterator it = B.basis().left_lower_bound(ar); + + for ( ; it != B_end && it->lc == ar; ++it) + { + std::size_t matched_block = std::distance(B_begin, it); + std::size_t c_block = C.find_block(A.basis().left_charge(k), it->rc); + if (c_block == C.n_blocks()) + c_block = C.insert_block(Matrix3(num_rows(A[k]), it->rs), A.basis().left_charge(k), it->rc); + boost::numeric::bindings::blas::gemm(conj_scales[k], A[k], B[matched_block], value_type(1), C[c_block]); } - - return ret; } +} - template - void gemm_trim_right(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - std::vector conj_scales = std::vector()) - { - typedef typename SymmGroup::charge charge; - typedef typename DualIndex::const_iterator const_iterator; - typedef typename Matrix3::value_type value_type; - - if (conj_scales.size() != B.n_blocks()) - conj_scales = std::vector(B.n_blocks(), 1.); - - C.clear(); - assert(B.basis().is_sorted()); - - const_iterator B_begin = B.basis().begin(); - const_iterator B_end = B.basis().end(); - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - - charge ar = A.basis().right_charge(k); - const_iterator it = B.basis().left_lower_bound(ar); - - for ( ; it != B_end && it->lc == ar; ++it) - { - std::size_t matched_block = std::distance(B_begin, it); - //assert(A.basis().left_has(it->rc)); - if (!A.basis().left_has(it->rc)) continue; - - std::size_t c_block = C.find_block(A.basis().left_charge(k), it->rc); - if (c_block == C.n_blocks()) - c_block = C.insert_block(Matrix3(num_rows(A[k]), it->rs), A.basis().left_charge(k), it->rc); - - boost::numeric::bindings::blas::gemm(conj_scales[matched_block], A[k], B[matched_block], value_type(1), C[c_block]); - } +/** @brief Same as [gemm_trim_right], but does not do any multiplication and returns only the dimensions */ +template +DualIndex gemm_trim_right_pretend(DualIndex const& A, + block_matrix const & B, + Index const & refIndex) +{ + typedef typename SymmGroup::charge charge; + typedef typename DualIndex::const_iterator const_iterator; + assert(B.basis().is_sorted()); + DualIndex ret; + const_iterator B_end = B.basis().end(); + for (std::size_t k = 0; k < A.size(); ++k) { + charge ar = A.right_charge(k); + const_iterator it = B.basis().left_lower_bound(ar); + for ( ; it != B_end && it->lc == ar; ++it) + { + if (!refIndex.has(it->rc)) + continue; + charge lc = A.left_charge(k); + charge rc = it->rc; + if (!ret.has(lc, rc)) + ret.insert(typename DualIndex::value_type(lc, rc, A.left_size(k), it->rs)); } } + return ret; +} - template - void gemm_trim(block_matrix const & A, - block_matrix const & B, - block_matrix & C, - std::vector conj_scales, - bool conjugate_a) - { - typedef typename SymmGroup::charge charge; - typedef typename DualIndex::const_iterator const_iterator; - typedef typename Matrix3::value_type value_type; - - assert(B.basis().is_sorted()); - assert( (conjugate_a && A.n_blocks() == conj_scales.size()) || (!conjugate_a && B.n_blocks() == conj_scales.size())); - C.clear(); - - for (std::size_t k = 0; k < A.n_blocks(); ++k) { - - charge al = A.basis().left_charge(k); - charge ar = A.basis().right_charge(k); - - std::size_t matched_block = B.basis().position(ar, al); - if (matched_block == B.n_blocks()) continue; - - std::size_t c_block = C.find_block(al, al); +/** @brief block_matrix multipication with right trimming (see abelian version of [gemm_trim_right]) */ +template +void gemm_trim_right(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + Index const & refIndex, + std::vector conj_scales = std::vector()) +{ + typedef typename SymmGroup::charge charge; + typedef typename DualIndex::const_iterator const_iterator; + typedef typename Matrix3::value_type value_type; + + if (conj_scales.size() != B.n_blocks()) + conj_scales = std::vector(B.n_blocks(), 1.); + C.clear(); + assert(B.basis().is_sorted()); + const_iterator B_begin = B.basis().begin(); + const_iterator B_end = B.basis().end(); + for (std::size_t k = 0; k < A.n_blocks(); ++k) { + charge ar = A.basis().right_charge(k); + const_iterator it = B.basis().left_lower_bound(ar); + for ( ; it != B_end && it->lc == ar; ++it) + { + std::size_t matched_block = std::distance(B_begin, it); + //assert(A.basis().left_has(it->rc)); + if (!refIndex.has(it->rc)) + continue; + std::size_t c_block = C.find_block(A.basis().left_charge(k), it->rc); if (c_block == C.n_blocks()) - c_block = C.insert_block(Matrix3(num_rows(A[k]), num_cols(B[matched_block])), al, al); - - //boost::numeric::bindings::blas::gemm(value_type(1), A[k], B[matched_block], value_type(1), C[c_block]); - boost::numeric::bindings::blas::gemm(conj_scales[ (conjugate_a) ? k : matched_block], A[k], B[matched_block], - value_type(1), C[c_block]); + c_block = C.insert_block(Matrix3(num_rows(A[k]), it->rs), A.basis().left_charge(k), it->rc); + boost::numeric::bindings::blas::gemm(conj_scales[matched_block], A[k], B[matched_block], value_type(1), C[c_block]); } } } +template +void gemm_trim(block_matrix const & A, + block_matrix const & B, + block_matrix & C, + std::vector conj_scales, + bool conjugate_a) +{ + typedef typename SymmGroup::charge charge; + typedef typename DualIndex::const_iterator const_iterator; + typedef typename Matrix3::value_type value_type; + assert(B.basis().is_sorted()); + assert( (conjugate_a && A.n_blocks() == conj_scales.size()) || (!conjugate_a && B.n_blocks() == conj_scales.size())); + C.clear(); + for (std::size_t k = 0; k < A.n_blocks(); ++k) { + charge al = A.basis().left_charge(k); + charge ar = A.basis().right_charge(k); + std::size_t matched_block = B.basis().position(ar, al); + if (matched_block == B.n_blocks()) continue; + std::size_t c_block = C.find_block(al, al); + if (c_block == C.n_blocks()) + c_block = C.insert_block(Matrix3(num_rows(A[k]), num_cols(B[matched_block])), al, al); + //boost::numeric::bindings::blas::gemm(value_type(1), A[k], B[matched_block], value_type(1), C[c_block]); + boost::numeric::bindings::blas::gemm(conj_scales[ (conjugate_a) ? k : matched_block], A[k], B[matched_block], + value_type(1), C[c_block]); + } +} + +} // gemm + #endif diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/site_hamil.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/site_hamil.hpp index 82cd2b155..22f424a79 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/site_hamil.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/site_hamil.hpp @@ -30,74 +30,87 @@ namespace contraction { - // forward declarations - template - MPSTensor - site_hamil_lbtm(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo); - - template - MPSTensor - site_hamil_rbtm(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo); - // ************************************************************* - - - template - MPSTensor - Engine>:: - site_hamil2(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo) - { - if ( (mpo.row_dim() - mpo.num_one_rows()) < (mpo.col_dim() - mpo.num_one_cols()) ) - return site_hamil_lbtm(ket_tensor, left, right, mpo); - else - return site_hamil_rbtm(ket_tensor, left, right, mpo); +// forward declarations +template +MPSTensor +site_hamil_lbtm(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian); + +template +MPSTensor +site_hamil_rbtm(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian); + +// ************************************************************* + +template +MPSTensor +Engine>:: +site_hamil2(MPSTensor ket_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian) +{ + if ( (mpo.row_dim() - mpo.num_one_rows()) < (mpo.col_dim() - mpo.num_one_cols()) ) + return site_hamil_lbtm(ket_tensor, ket_tensor, left, right, mpo, isHermitian); + else + return site_hamil_rbtm(ket_tensor, ket_tensor, left, right, mpo, isHermitian); +} + +template +MPSTensor +Engine>:: +site_hamil2(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left,Boundary const & right, + MPOTensor const & mpo, bool isHermitian) +{ + if ( (mpo.row_dim() - mpo.num_one_rows()) < (mpo.col_dim() - mpo.num_one_cols()) ) + return site_hamil_lbtm(ket_tensor, bra_tensor, left, right, mpo, isHermitian); + else + return site_hamil_rbtm(ket_tensor, bra_tensor, left, right, mpo, isHermitian); +} + +// ************************************************************* +// specialized variants + +template +MPSTensor +site_hamil_lbtm(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian) +{ + // Types definition + typedef typename SymmGroup::charge charge; + typedef typename MPOTensor::index_type index_type; + typedef typename Matrix::value_type value_type; + // Setup indices + Index const & physical_i = ket_tensor.site_dim(); + Index const & left_i = bra_tensor.row_dim(); + Index right_i = ket_tensor.col_dim(); + Index out_left_i = physical_i * left_i; + Index right_i_bra = bra_tensor.col_dim(); + common_subset(out_left_i, right_i_bra); + ProductBasis out_left_pb(physical_i, left_i); + ProductBasis in_right_pb(physical_i, right_i, + boost::lambda::bind(static_cast(SymmGroup::fuse), + -boost::lambda::_1, boost::lambda::_2)); + bra_tensor.make_right_paired(); + Index indexForTrim = bra_tensor.data().left_basis(); + contraction::common::BoundaryMPSProduct t(ket_tensor, left, mpo, indexForTrim, isHermitian); + // Prepares final data + MPSTensor ret; + ret.phys_i = bra_tensor.site_dim(); + ret.left_i = bra_tensor.row_dim(); + ret.right_i = bra_tensor.col_dim(); + index_type loop_max = mpo.col_dim(); + DualIndex ket_basis_transpose = ket_tensor.data().basis(); + for (std::size_t i = 0; i < ket_basis_transpose.size(); ++i) { + std::swap(ket_basis_transpose[i].lc, ket_basis_transpose[i].rc); + std::swap(ket_basis_transpose[i].ls, ket_basis_transpose[i].rs); } - - // ************************************************************* - // specialized variants - - template - MPSTensor - site_hamil_lbtm(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo) - { - typedef typename SymmGroup::charge charge; - typedef typename MPOTensor::index_type index_type; - typedef typename Matrix::value_type value_type; - - contraction::common::BoundaryMPSProduct t(ket_tensor, left, mpo); - - Index const & physical_i = ket_tensor.site_dim(), - & left_i = ket_tensor.row_dim(); - Index right_i = ket_tensor.col_dim(), - out_left_i = physical_i * left_i; - - common_subset(out_left_i, right_i); - ProductBasis out_left_pb(physical_i, left_i); - ProductBasis in_right_pb(physical_i, right_i, - boost::lambda::bind(static_cast(SymmGroup::fuse), - -boost::lambda::_1, boost::lambda::_2)); - - MPSTensor ret; - ret.phys_i = ket_tensor.site_dim(); ret.left_i = ket_tensor.row_dim(); ret.right_i = ket_tensor.col_dim(); - index_type loop_max = mpo.col_dim(); - - DualIndex ket_basis_transpose = ket_tensor.data().basis(); - for (std::size_t i = 0; i < ket_basis_transpose.size(); ++i) { - std::swap(ket_basis_transpose[i].lc, ket_basis_transpose[i].rc); - std::swap(ket_basis_transpose[i].ls, ket_basis_transpose[i].rs); - } - + bra_tensor.make_right_paired(); + DualIndex bra_basis = bra_tensor.data().basis(); #ifdef USE_AMBIENT { block_matrix empty; @@ -119,106 +132,96 @@ namespace contraction { parallel::sync(); #else - omp_for(index_type b2, parallel::range(0,loop_max), { - ContractionGrid contr_grid(mpo, 0, 0); - block_matrix tmp, tmp2; - - typename MPOTensor::col_proxy cp = mpo.column(b2); - index_type num_ops = std::distance(cp.begin(), cp.end()); - if (num_ops > 3) { - SU2::lbtm_kernel_rp(b2, contr_grid, left, t, mpo, ket_basis_transpose, right_i, out_left_i, in_right_pb, out_left_pb); - reshape_right_to_left_new(physical_i, left_i, right_i, contr_grid(0,0), tmp2); - - contr_grid(0,0).clear(); - swap(contr_grid(0,0), tmp2); - } - else { - SU2::lbtm_kernel(b2, contr_grid, left, t, mpo, ket_basis_transpose, right_i, out_left_i, in_right_pb, out_left_pb); - } - - if (mpo.herm_info.right_skip(b2)) { - std::vector phases = ::contraction::common::conjugate_phases(adjoint(right[mpo.herm_info.right_conj(b2)]), mpo, b2, false, true); - ::SU2::gemm_trim(contr_grid(0,0), adjoint(right[mpo.herm_info.right_conj(b2)]), tmp, phases, false); - } - else - ::SU2::gemm_trim(contr_grid(0,0), right[b2], tmp, std::vector(contr_grid(0,0).n_blocks(), 1.), true); - + omp_for(index_type b2, parallel::range(0,loop_max), { + ContractionGrid contr_grid(mpo, 0, 0); + block_matrix tmp, tmp2; + typename MPOTensor::col_proxy cp = mpo.column(b2); + index_type num_ops = std::distance(cp.begin(), cp.end()); + if (num_ops > 3) { + SU2::lbtm_kernel_rp(b2, contr_grid, left, t, mpo, ket_basis_transpose, right_i, out_left_i, in_right_pb, out_left_pb); + reshape_right_to_left_new(physical_i, left_i, right_i, contr_grid(0,0), tmp2); contr_grid(0,0).clear(); - - if (num_ops > 3) + swap(contr_grid(0,0), tmp2); + } + else { + SU2::lbtm_kernel(b2, contr_grid, left, t, mpo, ket_basis_transpose, right_i, out_left_i, in_right_pb, out_left_pb); + } + if (mpo.herm_info.right_skip(b2) && isHermitian) { + std::vector phases = ::contraction::common::conjugate_phases(adjoint(right[mpo.herm_info.right_conj(b2)]), mpo, b2, false, true); + ::SU2::gemm_trim(contr_grid(0,0), adjoint(right[mpo.herm_info.right_conj(b2)]), tmp, phases, false); + } + else + ::SU2::gemm_trim(contr_grid(0,0), right[b2], tmp, std::vector(contr_grid(0,0).n_blocks(), 1.), true); + contr_grid(0,0).clear(); + if (num_ops > 3) { for (std::size_t k = 0; k < tmp.n_blocks(); ++k) if (!out_left_i.has(tmp.basis().left_charge(k))) tmp.remove_block(k--); - - parallel_critical - for (std::size_t k = 0; k < tmp.n_blocks(); ++k) - ret.data().match_and_add_block(tmp[k], tmp.basis().left_charge(k), tmp.basis().right_charge(k)); - }); + } + parallel_critical + for (std::size_t k = 0; k < tmp.n_blocks(); ++k) + ret.data().match_and_add_block(tmp[k], tmp.basis().left_charge(k), tmp.basis().right_charge(k)); + }); #endif - return ret; - } - - template - MPSTensor - site_hamil_rbtm(MPSTensor ket_tensor, - Boundary const & left, - Boundary const & right, - MPOTensor const & mpo) - { - typedef typename SymmGroup::charge charge; - typedef typename MPOTensor::index_type index_type; - typedef typename Matrix::value_type value_type; - - contraction::common::MPSBoundaryProduct t(ket_tensor, right, mpo); - DualIndex kb1 = ket_tensor.data().basis(); - - Index const & physical_i = ket_tensor.site_dim(), - right_i = ket_tensor.col_dim(); - Index left_i = ket_tensor.row_dim(), - out_right_i = adjoin(physical_i) * right_i; - - common_subset(out_right_i, left_i); - ProductBasis in_left_pb(physical_i, left_i); - ProductBasis out_right_pb(physical_i, right_i, - boost::lambda::bind(static_cast(SymmGroup::fuse), - -boost::lambda::_1, boost::lambda::_2)); - block_matrix collector; - MPSTensor ret; - ret.phys_i = ket_tensor.site_dim(); ret.left_i = ket_tensor.row_dim(); ret.right_i = ket_tensor.col_dim(); - - index_type loop_max = mpo.row_dim(); - omp_for(index_type b1, parallel::range(0,loop_max), { - - block_matrix tmp, tmp2; - - SU2::task_capsule tasks_cap; - SU2::rbtm_tasks(b1, t, mpo, ket_tensor.data().basis(), left_i, out_right_i, in_left_pb, out_right_pb, tasks_cap); - if (mpo.herm_info.left_skip(b1)) - SU2::rbtm_axpy_gemm(b1, tasks_cap, tmp2, out_right_i, left, mpo, conjugate(left[mpo.herm_info.left_conj(b1)]), t); - else - SU2::rbtm_axpy_gemm(b1, tasks_cap, tmp2, out_right_i, left, mpo, transpose(left[b1]), t); - t.free(b1); - - //SU2::rbtm_kernel(b1, tmp, left, t, mpo, ket_tensor.data().basis(), left_i, out_right_i, in_left_pb, out_right_pb); - - //if (mpo.herm_info.left_skip(b1)) { - // std::vector phases = ::contraction::common::conjugate_phases(left[mpo.herm_info.left_conj(b1)], mpo, b1, true, false); - // ::SU2::gemm_trim(left[mpo.herm_info.left_conj(b1)], tmp, tmp2, phases, true); - //} - //else - // ::SU2::gemm_trim(transpose(left[b1]), tmp, tmp2, std::vector(tmp.n_blocks(), 1.), false); - //tmp.clear(); - - parallel_critical - for (std::size_t k = 0; k < tmp2.n_blocks(); ++k) - collector.match_and_add_block(tmp2[k], tmp2.basis().left_charge(k), tmp2.basis().right_charge(k)); - }); - - reshape_right_to_left_new(physical_i, left_i, right_i, collector, ret.data()); - DualIndex kb2 = ket_tensor.data().basis(); - if (!(kb1 == kb2)) throw std::runtime_error("XX\n"); - return ret; - } + return ret; +} + +template +MPSTensor +site_hamil_rbtm(MPSTensor ket_tensor, MPSTensor const & bra_tensor, + Boundary const & left, Boundary const & right, + MPOTensor const & mpo, bool isHermitian) +{ + typedef typename SymmGroup::charge charge; + typedef typename MPOTensor::index_type index_type; + typedef typename Matrix::value_type value_type; + bra_tensor.make_left_paired(); + Index indexForTrim = bra_tensor.data().left_basis(); + contraction::common::MPSBoundaryProduct t(ket_tensor, right, mpo, indexForTrim, isHermitian); + DualIndex kb1 = ket_tensor.data().basis(); + Index const & physical_i = ket_tensor.site_dim(), + right_i = bra_tensor.col_dim(); + Index left_i = ket_tensor.row_dim(), + out_right_i = adjoin(physical_i) * right_i; + Index left_i_ket = ket_tensor.row_dim(); + common_subset(out_right_i, left_i_ket); + ProductBasis in_left_pb(physical_i, left_i); + ProductBasis out_right_pb(physical_i, right_i, + boost::lambda::bind(static_cast(SymmGroup::fuse), + -boost::lambda::_1, boost::lambda::_2)); + block_matrix collector; + MPSTensor ret; + ret.phys_i = bra_tensor.site_dim(); + ret.left_i = bra_tensor.row_dim(); + ret.right_i = bra_tensor.col_dim(); + index_type loop_max = mpo.row_dim(); + omp_for(index_type b1, parallel::range(0,loop_max), { + block_matrix tmp, tmp2; + SU2::task_capsule tasks_cap; + SU2::rbtm_tasks(b1, t, mpo, ket_tensor.data().basis(), left_i, out_right_i, in_left_pb, out_right_pb, tasks_cap); + if (mpo.herm_info.left_skip(b1) && isHermitian) + SU2::rbtm_axpy_gemm(b1, tasks_cap, tmp2, out_right_i, left, mpo, conjugate(left[mpo.herm_info.left_conj(b1)]), t); + else + SU2::rbtm_axpy_gemm(b1, tasks_cap, tmp2, out_right_i, left, mpo, transpose(left[b1]), t); + t.free(b1); + //SU2::rbtm_kernel(b1, tmp, left, t, mpo, ket_tensor.data().basis(), left_i, out_right_i, in_left_pb, out_right_pb); + //if (mpo.herm_info.left_skip(b1)) { + // std::vector phases = ::contraction::common::conjugate_phases(left[mpo.herm_info.left_conj(b1)], mpo, b1, true, false); + // ::SU2::gemm_trim(left[mpo.herm_info.left_conj(b1)], tmp, tmp2, phases, true); + //} + //else + // ::SU2::gemm_trim(transpose(left[b1]), tmp, tmp2, std::vector(tmp.n_blocks(), 1.), false); + //tmp.clear(); + parallel_critical + for (std::size_t k = 0; k < tmp2.n_blocks(); ++k) + collector.match_and_add_block(tmp2[k], tmp2.basis().left_charge(k), tmp2.basis().right_charge(k)); + }); + reshape_right_to_left_new(physical_i, left_i, right_i, collector, ret.data()); + DualIndex kb2 = ket_tensor.data().basis(); + if (!(kb1 == kb2)) + throw std::runtime_error("XX\n"); + return ret; +} } // namespace contraction diff --git a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/zero_site_hamil.hpp b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/zero_site_hamil.hpp index db801a1c3..e83cc732f 100644 --- a/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/zero_site_hamil.hpp +++ b/dmrg/framework/dmrg/mp_tensors/contractions/non-abelian/zero_site_hamil.hpp @@ -33,31 +33,40 @@ namespace contraction { template block_matrix zerosite_hamil_lbtm(block_matrix bra_tensor, block_matrix ket_tensor, Boundary const & left, - Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right); + Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian); + +template +block_matrix +zerosite_hamil_lbtm(block_matrix ket_tensor, Boundary const & left, + Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian); template block_matrix Engine>:: zerosite_hamil2(block_matrix bra_tensor, block_matrix ket_tensor, Boundary const & left, - Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right) + Boundary const & right, MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian) { - return zerosite_hamil_lbtm(bra_tensor, ket_tensor, left, right, mpo_left, mpo_right); + return zerosite_hamil_lbtm(bra_tensor, ket_tensor, left, right, mpo_left, mpo_right, isHermitian); } template block_matrix Engine>:: zerosite_hamil2(block_matrix ket_tensor, Boundary const & left, Boundary const & right, - MPOTensor const & mpo_left, MPOTensor const & mpo_right) + MPOTensor const & mpo_left, MPOTensor const & mpo_right, bool isHermitian) { - return zerosite_hamil_lbtm(ket_tensor, ket_tensor, left, right, mpo_left, mpo_right); + return zerosite_hamil_lbtm(ket_tensor, left, right, mpo_left, mpo_right, isHermitian); } template block_matrix zerosite_hamil_lbtm_kernel(block_matrix const & bra_tensor, block_matrix ket_tensor, Boundary const & left, Boundary const & right, - MPOTensor const & mpo_left, MPOTensor const & mpo_right) + MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian) { // General types and variables typedef typename SymmGroup::charge charge; @@ -65,14 +74,14 @@ zerosite_hamil_lbtm_kernel(block_matrix const & bra_tensor, b typedef typename Matrix::value_type value_type; block_matrix ret; // Contraction with the boundary - contraction::common::BoundaryMPSProduct t(ket_tensor, left, mpo_right, false); + contraction::common::BoundaryMPSProduct t(ket_tensor, left, mpo_right, isHermitian, false); index_type loop_max = mpo_right.row_dim(); // Final contraction with the right boundary omp_for(index_type b2, parallel::range(0,loop_max), { // Variables and types block_matrix tmp, tmp2, local; // Contraction - if (mpo_right.herm_info.left_skip(b2)) { + if (mpo_right.herm_info.left_skip(b2) && isHermitian) { //std::vector phases = ::contraction::common::conjugate_phases(adjoint(right[mpo_left.herm_info.right_conj(b2)]), mpo_left, b2, false, true); //::SU2::gemm_trim(t.at(b2, local), adjoint(right[mpo_left.herm_info.right_conj(b2)]), tmp, phases, false); ::SU2::gemm_trim(t.at(b2, local), adjoint(right[mpo_left.herm_info.right_conj(b2)]), tmp, std::vector(adjoint(right[mpo_left.herm_info.right_conj(b2)]).n_blocks(), 1.), false); @@ -91,18 +100,20 @@ template block_matrix zerosite_hamil_lbtm(block_matrix ket_tensor, Boundary const & left, Boundary const & right, MPOTensor const & mpo_left, - MPOTensor const & mpo_right) + MPOTensor const & mpo_right, bool isHermitian) { - return zerosite_hamil_lbtm_kernel(ket_tensor, ket_tensor, left, right, mpo_left, mpo_right); + return zerosite_hamil_lbtm_kernel(ket_tensor, ket_tensor, left, right, mpo_left, mpo_right, isHermitian); } template block_matrix zerosite_hamil_lbtm(block_matrix bra_tensor, block_matrix ket_tensor, Boundary const & left, Boundary const & right, - MPOTensor const & mpo_left, MPOTensor const & mpo_right) + MPOTensor const & mpo_left, MPOTensor const & mpo_right, + bool isHermitian) { - return zerosite_hamil_lbtm_kernel(bra_tensor, ket_tensor, left, right, mpo_left, mpo_right); + //return zerosite_hamil_lbtm_kernel(bra_tensor, ket_tensor, left, right, mpo_left, mpo_right, isHermitian); + throw std::runtime_error("Zero site Hamiltonian for bra != ket NYI"); } } // namespace contraction diff --git a/dmrg/framework/dmrg/mp_tensors/mps_mpo_detail.h b/dmrg/framework/dmrg/mp_tensors/mps_mpo_detail.h new file mode 100644 index 000000000..8374de820 --- /dev/null +++ b/dmrg/framework/dmrg/mp_tensors/mps_mpo_detail.h @@ -0,0 +1,62 @@ +/***************************************************************************** + * + * ALPS MPS DMRG Project + * + * Copyright (C) 2021 Institute for Theoretical Physics, ETH Zurich + * 2021 by Alberto Baiardi + * + * This software is part of the ALPS Applications, published under the ALPS + * Application License; you can use, redistribute it and/or modify it under + * the terms of the license, either version 1 or (at your option) any later + * version. + * + * You should have received a copy of the ALPS Application License along with + * the ALPS Applications; see the file LICENSE.txt. If not, the license is also + * available from http://alps.comp-phys.org/. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef MPS_MPO_DETAIL_H +#define MPS_MPO_DETAIL_H + +namespace mps_mpo_detail { + +template +Boundary +mixed_left_boundary(MPS const & bra, MPS const & ket) +{ + assert(ket.length() == bra.length()); + Index i = ket[0].row_dim(); + Index j = bra[0].row_dim(); + Boundary ret(i, j, 1); + for(typename Index::basis_iterator it1 = i.basis_begin(); !it1.end(); ++it1) + for(typename Index::basis_iterator it2 = j.basis_begin(); !it2.end(); ++it2) + ret[0](*it1, *it2) = 1; + return ret; +} + +template +Boundary +mixed_right_boundary(MPS const & bra, MPS const & ket) +{ + assert(ket.length() == bra.length()); + Index j = ket[ket.length()-1].col_dim(); + Index i = bra[bra.length()-1].col_dim(); + Boundary ret(i, j, 1); + for(typename Index::basis_iterator it1 = i.basis_begin(); !it1.end(); ++it1) + for(typename Index::basis_iterator it2 = j.basis_begin(); !it2.end(); ++it2) + ret[0](*it1, *it2) = 1; + return ret; +} + +} // mps_mpo_detail + +#endif \ No newline at end of file diff --git a/dmrg/framework/dmrg/mp_tensors/mps_mpo_ops.h b/dmrg/framework/dmrg/mp_tensors/mps_mpo_ops.h index 490a7c155..d8b7cf0d5 100644 --- a/dmrg/framework/dmrg/mp_tensors/mps_mpo_ops.h +++ b/dmrg/framework/dmrg/mp_tensors/mps_mpo_ops.h @@ -4,6 +4,7 @@ * * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich * 2011-2011 by Bela Bauer + * 2021 by Alberto Baiardi * * This software is part of the ALPS Applications, published under the ALPS * Application License; you can use, redistribute it and/or modify it under @@ -30,107 +31,98 @@ #include "dmrg/mp_tensors/mps.h" #include "dmrg/mp_tensors/mpo.h" #include "dmrg/mp_tensors/twositetensor.h" - #include "dmrg/mp_tensors/special_mpos.h" #include "dmrg/mp_tensors/contractions.h" - #include "dmrg/utils/utils.hpp" #include "utils/traits.hpp" +#include "mps_mpo_detail.h" +// Forward declaration template -std::vector > -left_mpo_overlaps(MPS const & mps, MPO const & mpo) -{ - assert(mpo.length() == mps.length()); - std::size_t L = mps.length(); - - std::vector > left_(L+1); - left_[0] = mps.left_boundary(); - - for (int i = 0; i < L; ++i) { - left_[i+1] = contraction::Engine::overlap_mpo_left_step(mps[i], mps[i], left_[i], mpo[i]); - } - return left_; -} +typename Matrix::value_type expval(MPS const & bra, MPS const & ket, + MPO const & mpo); template -std::vector > -right_mpo_overlaps(MPS const & mps, MPO const & mpo) -{ - assert(mpo.length() == mps.length()); - std::size_t L = mps.length(); - - std::vector > right_(L+1); - right_[L] = mps.right_boundary(); - - for (int i = L-1; i >= 0; --i) { - right_[i] = contraction::Engine::overlap_mpo_right_step(mps[i], mps[i], right_[i+1], mpo[i]); - } - return right_; -} +typename Matrix::value_type expvalFromRight(MPS const & bra, MPS const & ket, + MPO const & mpo); +/** + * @brief Method to calculate the expectation value choosing the starting site. + * + * The expectation value is calculated by contracting the full MPS/MPO network. + * This can be done starting either from the first or from the last site of the + * lattice. The first option is activated with d == 0, the second one with + * d != 0 + * + * @param mps Input MPS + * @param mpo Input MPO + * @param d If == 0, starts from the first site, otherwise, starts from the last site. + * @return Matrix::value_type Expectation value < mps | H | mps > + */ template -double expval(MPS const & mps, MPO const & mpo, int d) +auto expval(MPS const & mps, MPO const & mpo, int d) { - if (d == 0) { - std::vector > left_ = left_mpo_overlaps(mps, mpo); - assert( check_real(left_[mps.length()][0].trace()) ); - return maquis::real(left_[mps.length()][0].trace()) + mpo.getCoreEnergy(); - } else { - std::vector > right_ = right_mpo_overlaps(mps, mpo); - assert( check_real(right_[0][0].trace()) ); - return maquis::real(right_[0][0].trace()) + mpo.getCoreEnergy(); - } -} - -namespace mps_mpo_detail { - - template - Boundary - mixed_left_boundary(MPS const & bra, MPS const & ket) - { - assert(ket.length() == bra.length()); - Index i = ket[0].row_dim(); - Index j = bra[0].row_dim(); - Boundary ret(i, j, 1); - - for(typename Index::basis_iterator it1 = i.basis_begin(); !it1.end(); ++it1) - for(typename Index::basis_iterator it2 = j.basis_begin(); !it2.end(); ++it2) - ret[0](*it1, *it2) = 1; - - return ret; - } + return (d == 0) ? expval(mps, mps, mpo) : expvalFromRight(mps, mps, mpo); } +/** + * @brief Method to calculate the matrix element of an operator between two different MPSs + * + * @param bra Input MPS representing the bra + * @param ket Input MPS representing the ket + * @param mpo Input MPO + * @return Matrix::value_type < bra | mpo | ket > + */ template -typename Matrix::value_type expval(MPS const & bra, - MPS const & ket, - MPO const & mpo, - bool verbose = false) +typename Matrix::value_type expval(MPS const & bra, MPS const & ket, + MPO const & mpo) { parallel::scheduler_balanced scheduler(bra.length()); assert(mpo.length() == bra.length() && bra.length() == ket.length()); std::size_t L = bra.length(); - Boundary left = mps_mpo_detail::mixed_left_boundary(bra, ket); - for (int i = 0; i < L; ++i) { parallel::guard proc(scheduler(i)); - if (verbose) - std::cout << "expval site " << i << std::endl; - left = contraction::Engine::overlap_mpo_left_step(bra[i], ket[i], left, mpo[i]); + left = contraction::Engine::overlap_mpo_left_step(bra[i], ket[i], left, mpo[i], false); } - - // MD: if bra and ket are different, result might be complex! return left.traces()[0] + mpo.getCoreEnergy(); } +/** + * @brief Method to calculate the matrix element of an operator between two different MPSs + * + * Unlike [expVal], this method contracts the network starting from the last site. + * + * @param bra Input MPS representing the bra + * @param ket Input MPS representing the ket + * @param mpo Input MPO + * @return Matrix::value_type < bra | mpo | ket > + */ +template +typename Matrix::value_type expvalFromRight(MPS const & bra, MPS const & ket, + MPO const & mpo) +{ + parallel::scheduler_balanced scheduler(bra.length()); + assert(mpo.length() == bra.length() && bra.length() == ket.length()); + std::size_t L = bra.length(); + Boundary right = mps_mpo_detail::mixed_right_boundary(bra, ket); + for (int i = L-1; i >= 0; --i) { + parallel::guard proc(scheduler(i)); + right = contraction::Engine::overlap_mpo_right_step(bra[i], ket[i], right, mpo[i], false); + } + return right.traces()[0]; +} +/** + * @brief Calculates the expectation value of an MPS over an MPO. + * @param mps Input MPS + * @param mpo Input MPO + * @return Matrix::value_type < mps | mpo | mps > + */ template -typename Matrix::value_type expval(MPS const & mps, MPO const & mpo, - bool verbose = false) +typename Matrix::value_type expval(MPS const & mps, MPO const & mpo) { - return expval(mps, mps, mpo, verbose); + return expval(mps, mps, mpo); } template diff --git a/dmrg/framework/dmrg/utils/DmrgParameters.h b/dmrg/framework/dmrg/utils/DmrgParameters.h index 832448dbb..a52e5c284 100644 --- a/dmrg/framework/dmrg/utils/DmrgParameters.h +++ b/dmrg/framework/dmrg/utils/DmrgParameters.h @@ -227,11 +227,6 @@ class ModelParameters : public BaseParameters add_option("orbital_order", "comma separated list of orbital numbers"); add_option("hf_occ", "comma separated list of orbital occupancies for Hartree Fock initial state"); - add_option("MEASURE_CONTINUUM[Psi energy]", "", value(false)); - add_option("MEASURE_CONTINUUM[Density]", "", value(true)); - add_option("MEASURE_CONTINUUM[Local density]", "", value(true)); - add_option("MEASURE_CONTINUUM[Onebody density matrix]", "", value(false)); - add_option("MEASURE[Density]", "", value(false)); add_option("MEASURE[Local density]", "", value(false)); add_option("MEASURE[Local density^2]", "", value(false)); diff --git a/dmrg/tests/CMakeLists.txt b/dmrg/tests/CMakeLists.txt index 3ea2b537c..1b7e2448d 100644 --- a/dmrg/tests/CMakeLists.txt +++ b/dmrg/tests/CMakeLists.txt @@ -30,6 +30,8 @@ if(BUILD_PREBO) target_link_libraries(test_prebo_symbolic_operator ${DMRG_APP_LIBRARIES}) add_executable(test_prebo_symbolic_jw prebo/SymbolicJordanWignerTest.cpp) target_link_libraries(test_prebo_symbolic_jw ${DMRG_APP_LIBRARIES}) + add_executable(test_mps_mpo_ops_prebo test_mps_mpo_ops/test_mps_mpo_ops_prebo.cpp) + target_link_libraries(test_mps_mpo_ops_prebo ${DMRG_APP_LIBRARIES}) endif(BUILD_PREBO) add_executable(test_integral_map test_integral_map.cpp) @@ -41,8 +43,14 @@ target_link_libraries(test_rel ${DMRG_APP_LIBRARIES}) add_executable(test_hirdm test_hirdm.cpp) target_link_libraries(test_hirdm ${DMRG_APP_LIBRARIES}) -add_executable(test_mps_mpo_ops test_mps_mpo_ops/test_mps_mpo_ops.cpp) -target_link_libraries(test_mps_mpo_ops ${DMRG_APP_LIBRARIES}) +add_executable(test_mps_mpo_ops_TwoU1 test_mps_mpo_ops/test_mps_mpo_ops_TwoU1.cpp) +target_link_libraries(test_mps_mpo_ops_TwoU1 ${DMRG_APP_LIBRARIES}) + +add_executable(test_mps_mpo_ops_electronic test_mps_mpo_ops/test_mps_mpo_ops_electronic.cpp) +target_link_libraries(test_mps_mpo_ops_electronic ${DMRG_APP_LIBRARIES}) + +add_executable(test_mps_overlap_electronic test_mps_mpo_ops/test_mps_overlap_electronic.cpp) +target_link_libraries(test_mps_overlap_electronic ${DMRG_APP_LIBRARIES}) add_executable(test_siteproblem test_mps_mpo_ops/test_siteproblem.cpp) target_link_libraries(test_siteproblem ${DMRG_APP_LIBRARIES}) diff --git a/dmrg/tests/Fixtures/RelativisticFixture.h b/dmrg/tests/Fixtures/RelativisticFixture.h new file mode 100644 index 000000000..0af4e5e39 --- /dev/null +++ b/dmrg/tests/Fixtures/RelativisticFixture.h @@ -0,0 +1,1012 @@ +/***************************************************************************** +* +* ALPS MPS DMRG Project +* +* Copyright (C) 2021 Institute for Theoretical Physics, ETH Zurich +* 2021- by Alberto Baiardi +* +* This software is part of the ALPS Applications, published under the ALPS +* Application License; you can use, redistribute it and/or modify it under +* the terms of the license, either version 1 or (at your option) any later +* version. +* +* You should have received a copy of the ALPS Application License along with +* the ALPS Applications; see the file LICENSE.txt. If not, the license is also +* available from http://alps.comp-phys.org/. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef TEST_RELATIVISTIC_FIXTURE_H +#define TEST_RELATIVISTIC_FIXTURE_H + +#include "maquis_dmrg.h" +#include "dmrg/block_matrix/symmetry.h" + + +/** + * @brief Fixture class for relativistic calculations. + * + * Relativistic test: N2+, (3e,8o) 3-21G basis. + * @ stknecht: please update description + */ +struct RelativisticFixture +{ + // Types definition + using ComplexIntegralMapType = typename maquis::integral_map>; + + /** @brief Constructor for the fixture class */ + RelativisticFixture() { + // Real-valued integrals + integralsComplex = ComplexIntegralMapType{ { { 1, 1, 1, 1 }, { 2.61972936056406e-01, -5.93576335462699e-17 } }, + { { 3, 1, 1, 1 }, { 1.26743997238509e-09, 9.20431282901706e-12 } }, + { { 1, 1, 3, 1 }, { 1.26743997238509e-09, 9.20431282901706e-12 } }, + { { 5, 1, 5, 1 }, { 7.34497110698912e-02, 4.26240897602650e-10 } }, + { { 7, 1, 5, 1 }, { 4.01669748480819e-09, 3.60591432811921e-09 } }, + { { 5, 1, 7, 1 }, { 4.01669748480819e-09, 3.60591432811921e-09 } }, + { { 1, 3, 1, 1 }, { 1.26743996410745e-09, -9.20429997217042e-12 } }, + { { 3, 3, 1, 1 }, { 2.61943485031872e-01, -2.00991307043607e-17 } }, + { { 1, 3, 3, 1 }, { 2.00381403996136e-02, -1.08420217248550e-18 } }, + { { 3, 3, 3, 1 }, { -1.27168924225649e-09, -9.73022387800160e-12 } }, + { { 5, 3, 5, 1 }, { -5.63030148897478e-09, -1.78997963409621e-09 } }, + { { 7, 3, 5, 1 }, { 2.22515327441311e-02, 4.31016204922364e-02 } }, + { { 5, 3, 7, 1 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 7, 3, 7, 1 }, { -4.28392084589810e-10, 3.43537540037891e-09 } }, + { { 5, 5, 1, 1 }, { 2.50873194689164e-01, 1.65168461057214e-17 } }, + { { 1, 5, 5, 1 }, { 7.34497110698912e-02, 1.89915634214172e-17 } }, + { { 3, 5, 5, 1 }, { -4.51615804178781e-09, 1.41887387086788e-09 } }, + { { 1, 5, 7, 1 }, { 3.38241175380762e-09, 2.85419828473184e-09 } }, + { { 7, 7, 1, 1 }, { 2.50828949907785e-01, -2.00659972392514e-17 } }, + { { 5, 7, 3, 1 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 1, 7, 5, 1 }, { 3.38241175232689e-09, -2.85419826760833e-09 } }, + { { 3, 7, 5, 1 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 1, 7, 7, 1 }, { 1.04255386413001e-02, 4.87890977618477e-19 } }, + { { 3, 7, 7, 1 }, { 2.15553000473605e-09, -1.31756361634581e-09 } }, + { { 1, 1, 1, 3 }, { 1.26743996410745e-09, -9.20429997217042e-12 } }, + { { 3, 1, 1, 3 }, { 2.00381403996136e-02, -1.08420217248550e-18 } }, + { { 1, 1, 3, 3 }, { 2.61943485031872e-01, -2.00991307043607e-17 } }, + { { 3, 1, 3, 3 }, { -1.27168924225649e-09, -9.73022387800160e-12 } }, + { { 5, 1, 5, 3 }, { -5.63030148897478e-09, -1.78997963409621e-09 } }, + { { 7, 1, 5, 3 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 5, 1, 7, 3 }, { 2.22515327441311e-02, 4.31016204922364e-02 } }, + { { 7, 1, 7, 3 }, { -4.28392084589810e-10, 3.43537540037891e-09 } }, + { { 3, 3, 1, 3 }, { -1.27168924927192e-09, 9.73023774231880e-12 } }, + { { 1, 3, 3, 3 }, { -1.27168924927192e-09, 9.73023774231880e-12 } }, + { { 3, 3, 3, 3 }, { 2.61914049687002e-01, 1.91403429621010e-17 } }, + { { 7, 3, 5, 3 }, { -1.11475987224334e-09, -4.36237058644354e-09 } }, + { { 5, 3, 7, 3 }, { -1.11475987224334e-09, -4.36237058644354e-09 } }, + { { 7, 3, 7, 3 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, + { { 7, 5, 1, 3 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, + { { 5, 5, 3, 3 }, { 2.50843627819692e-01, 3.76855130433924e-17 } }, + { { 1, 5, 5, 3 }, { -4.51615803079038e-09, -1.41887387023288e-09 } }, + { { 3, 5, 5, 3 }, { 1.48617254260414e-02, -4.33680868994202e-19 } }, + { { 1, 5, 7, 3 }, { 2.22515329942571e-02, 4.31016203631070e-02 } }, + { { 3, 5, 7, 3 }, { -2.00828744878274e-09, -2.74866711310747e-09 } }, + { { 7, 7, 3, 3 }, { 2.50799402750969e-01, 1.10201871793512e-18 } }, + { { 3, 7, 5, 3 }, { -2.00828744429202e-09, 2.74866710701661e-09 } }, + { { 1, 7, 7, 3 }, { 2.15552999444319e-09, 1.31756362061684e-09 } }, + { { 3, 7, 7, 3 }, { 3.20339000240785e-02, -3.46944695195361e-18 } }, + { { 5, 1, 1, 5 }, { 7.34497110698912e-02, 1.89915634214172e-17 } }, + { { 7, 1, 1, 5 }, { 3.38241175380762e-09, 2.85419828473184e-09 } }, + { { 5, 1, 3, 5 }, { -4.51615804178781e-09, 1.41887387086788e-09 } }, + { { 1, 1, 5, 5 }, { 2.50873194689164e-01, 1.65168461057214e-17 } }, + { { 5, 3, 1, 5 }, { -4.51615803079038e-09, -1.41887387023288e-09 } }, + { { 7, 3, 1, 5 }, { 2.22515329942571e-02, 4.31016203631070e-02 } }, + { { 5, 3, 3, 5 }, { 1.48617254260414e-02, -4.33680868994202e-19 } }, + { { 7, 3, 3, 5 }, { -2.00828744878274e-09, -2.74866711310747e-09 } }, + { { 3, 3, 5, 5 }, { 2.50843627819692e-01, 3.76855130433924e-17 } }, + { { 1, 3, 7, 5 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, + { { 1, 5, 1, 5 }, { 7.34497110698911e-02, -4.26240859619522e-10 } }, + { { 3, 5, 1, 5 }, { -5.63030150059789e-09, 1.78997963407439e-09 } }, + { { 1, 5, 3, 5 }, { -5.63030150059789e-09, 1.78997963407439e-09 } }, + { { 5, 5, 5, 5 }, { 2.46623945475382e-01, 7.18015643244974e-19 } }, + { { 1, 7, 1, 5 }, { 4.01669748364437e-09, -3.60591431030523e-09 } }, + { { 3, 7, 1, 5 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, + { { 1, 7, 3, 5 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 3, 7, 3, 5 }, { -1.11475987592073e-09, 4.36237059349358e-09 } }, + { { 7, 7, 5, 5 }, { 2.46582791504814e-01, 9.33242001386412e-19 } }, + { { 5, 7, 7, 5 }, { 1.31792902727351e-02, 7.04731412115578e-19 } }, + { { 5, 1, 1, 7 }, { 3.38241175232689e-09, -2.85419826760833e-09 } }, + { { 7, 1, 1, 7 }, { 1.04255386413001e-02, 4.87890977618477e-19 } }, + { { 5, 1, 3, 7 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 7, 1, 3, 7 }, { 2.15553000473605e-09, -1.31756361634581e-09 } }, + { { 3, 1, 5, 7 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 1, 1, 7, 7 }, { 2.50828949907785e-01, -2.00659972392514e-17 } }, + { { 7, 3, 1, 7 }, { 2.15552999444319e-09, 1.31756362061684e-09 } }, + { { 5, 3, 3, 7 }, { -2.00828744429202e-09, 2.74866710701661e-09 } }, + { { 7, 3, 3, 7 }, { 3.20339000240785e-02, -3.46944695195361e-18 } }, + { { 3, 3, 7, 7 }, { 2.50799402750969e-01, 1.10201871793512e-18 } }, + { { 1, 5, 1, 7 }, { 4.01669748364437e-09, -3.60591431030523e-09 } }, + { { 3, 5, 1, 7 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 1, 5, 3, 7 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, + { { 3, 5, 3, 7 }, { -1.11475987592073e-09, 4.36237059349358e-09 } }, + { { 7, 5, 5, 7 }, { 1.31792902727351e-02, 7.04731412115578e-19 } }, + { { 5, 5, 7, 7 }, { 2.46582791504814e-01, 9.33242001386412e-19 } }, + { { 3, 7, 1, 7 }, { -4.28392074105941e-10, -3.43537539483338e-09 } }, + { { 1, 7, 3, 7 }, { -4.28392074105941e-10, -3.43537539483338e-09 } }, + { { 3, 7, 3, 7 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, + { { 7, 7, 7, 7 }, { 2.46541664704192e-01, 1.14435014084414e-18 } }, + { { 3, 1, 3, 2 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 5, 1, 7, 2 }, { -3.44264963011916e-09, -9.90112075686836e-12 } }, + { { 7, 1, 7, 2 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 5, 3, 5, 2 }, { -7.84227887895554e-10, 8.65456802951857e-10 } }, + { { 7, 3, 7, 2 }, { -8.11616426840793e-10, -1.67305273292072e-09 } }, + { { 7, 5, 3, 2 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 1, 5, 7, 2 }, { -4.07154503624496e-09, -3.34683197320015e-10 } }, + { { 3, 5, 7, 2 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 1, 7, 5, 2 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 3, 7, 7, 2 }, { -1.49528281775848e-09, 1.95530142301122e-09 } }, + { { 3, 1, 1, 4 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 5, 1, 5, 4 }, { 1.76420137225424e-09, -1.05104055409810e-10 } }, + { { 7, 1, 5, 4 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 5, 1, 7, 4 }, { -5.50878617767860e-02, -1.99532026191666e-03 } }, + { { 7, 1, 7, 4 }, { -2.71542765827455e-09, -1.76543336029064e-09 } }, + { { 7, 3, 5, 4 }, { 7.35799852035404e-10, 8.96392999081955e-10 } }, + { { 5, 3, 7, 4 }, { 4.05111132035920e-09, 1.17669809883779e-09 } }, + { { 7, 3, 7, 4 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 7, 5, 1, 4 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 1, 5, 5, 4 }, { 1.64913548399047e-09, 1.70894048294891e-10 } }, + { { 3, 5, 5, 4 }, { -2.77775993160252e-04, 3.77410302057860e-03 } }, + { { 1, 5, 7, 4 }, { -5.50878617883651e-02, -1.99531994223258e-03 } }, + { { 3, 5, 7, 4 }, { 4.67622884828570e-09, -6.98952045491450e-10 } }, + { { 1, 7, 7, 4 }, { -2.90052566280734e-09, 2.04564331648436e-09 } }, + { { 3, 7, 7, 4 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 5, 1, 3, 6 }, { -1.76420137101272e-09, 1.05104052115801e-10 } }, + { { 7, 1, 3, 6 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 3, 1, 7, 6 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 5, 3, 1, 6 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, + { { 7, 3, 3, 6 }, { -7.35799849724064e-10, -8.96392999344636e-10 } }, + { { 1, 5, 3, 6 }, { -1.64913548274895e-09, -1.70894051588900e-10 } }, + { { 3, 5, 3, 6 }, { 2.77775993160252e-04, -3.77410302057860e-03 } }, + { { 7, 5, 7, 6 }, { -2.10829501478453e-03, -9.24701177434334e-03 } }, + { { 1, 7, 1, 6 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 5, 1, 1, 8 }, { 3.44264964154066e-09, 9.90113246252263e-12 } }, + { { 7, 1, 1, 8 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 5, 1, 3, 8 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, + { { 7, 1, 3, 8 }, { 2.71542765796015e-09, 1.76543336019022e-09 } }, + { { 3, 1, 5, 8 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 7, 3, 1, 8 }, { 8.11616423423967e-10, 1.67305274317960e-09 } }, + { { 5, 3, 3, 8 }, { -4.05111132068935e-09, -1.17669809910942e-09 } }, + { { 7, 3, 3, 8 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 1, 5, 1, 8 }, { 4.07154504766646e-09, 3.34683209025669e-10 } }, + { { 3, 5, 1, 8 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 1, 5, 3, 8 }, { 5.50878617883651e-02, 1.99531994223259e-03 } }, + { { 3, 5, 3, 8 }, { -4.67622884853612e-09, 6.98952045795709e-10 } }, + { { 7, 5, 5, 8 }, { 2.10829501478453e-03, 9.24701177434335e-03 } }, + { { 3, 7, 1, 8 }, { 1.49528282810068e-09, -1.95530142616690e-09 } }, + { { 1, 7, 3, 8 }, { 2.90052566249363e-09, -2.04564331631174e-09 } }, + { { 3, 7, 3, 8 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 3, 2, 3, 1 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 7, 2, 5, 1 }, { -3.44264963011916e-09, -9.90112075686836e-12 } }, + { { 7, 2, 7, 1 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 1, 4, 3, 1 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 5, 4, 5, 1 }, { 1.76420137225424e-09, -1.05104055409810e-10 } }, + { { 7, 4, 5, 1 }, { -5.50878617767860e-02, -1.99532026191666e-03 } }, + { { 5, 4, 7, 1 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 7, 4, 7, 1 }, { -2.71542765827455e-09, -1.76543336029064e-09 } }, + { { 7, 6, 3, 1 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 3, 6, 5, 1 }, { -1.76420137101272e-09, 1.05104052115801e-10 } }, + { { 3, 6, 7, 1 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 5, 8, 3, 1 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 1, 8, 5, 1 }, { 3.44264964154066e-09, 9.90113246252263e-12 } }, + { { 3, 8, 5, 1 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, + { { 1, 8, 7, 1 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 3, 8, 7, 1 }, { 2.71542765796015e-09, 1.76543336019022e-09 } }, + { { 5, 2, 5, 3 }, { -7.84227887895554e-10, 8.65456802951857e-10 } }, + { { 7, 2, 7, 3 }, { -8.11616426840793e-10, -1.67305273292072e-09 } }, + { { 7, 4, 5, 3 }, { 4.05111132035920e-09, 1.17669809883779e-09 } }, + { { 5, 4, 7, 3 }, { 7.35799852035404e-10, 8.96392999081955e-10 } }, + { { 7, 4, 7, 3 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 1, 6, 5, 3 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, + { { 3, 6, 7, 3 }, { -7.35799849724064e-10, -8.96392999344636e-10 } }, + { { 3, 8, 5, 3 }, { -4.05111132068935e-09, -1.17669809910942e-09 } }, + { { 1, 8, 7, 3 }, { 8.11616423423967e-10, 1.67305274317960e-09 } }, + { { 3, 8, 7, 3 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 7, 2, 1, 5 }, { -4.07154503624496e-09, -3.34683197320015e-10 } }, + { { 7, 2, 3, 5 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 3, 2, 7, 5 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 5, 4, 1, 5 }, { 1.64913548399047e-09, 1.70894048294891e-10 } }, + { { 7, 4, 1, 5 }, { -5.50878617883651e-02, -1.99531994223258e-03 } }, + { { 5, 4, 3, 5 }, { -2.77775993160252e-04, 3.77410302057860e-03 } }, + { { 7, 4, 3, 5 }, { 4.67622884828570e-09, -6.98952045491450e-10 } }, + { { 1, 4, 7, 5 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 3, 6, 1, 5 }, { -1.64913548274895e-09, -1.70894051588900e-10 } }, + { { 3, 6, 3, 5 }, { 2.77775993160252e-04, -3.77410302057860e-03 } }, + { { 7, 6, 7, 5 }, { -2.10829501478453e-03, -9.24701177434334e-03 } }, + { { 1, 8, 1, 5 }, { 4.07154504766646e-09, 3.34683209025669e-10 } }, + { { 3, 8, 1, 5 }, { 5.50878617883651e-02, 1.99531994223259e-03 } }, + { { 1, 8, 3, 5 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 3, 8, 3, 5 }, { -4.67622884853612e-09, 6.98952045795709e-10 } }, + { { 5, 8, 7, 5 }, { 2.10829501478453e-03, 9.24701177434335e-03 } }, + { { 5, 2, 1, 7 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 7, 2, 3, 7 }, { -1.49528281775848e-09, 1.95530142301122e-09 } }, + { { 7, 4, 1, 7 }, { -2.90052566280734e-09, 2.04564331648436e-09 } }, + { { 7, 4, 3, 7 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 1, 6, 1, 7 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 3, 8, 1, 7 }, { 2.90052566249363e-09, -2.04564331631174e-09 } }, + { { 1, 8, 3, 7 }, { 1.49528282810068e-09, -1.95530142616690e-09 } }, + { { 3, 8, 3, 7 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 7, 2, 5, 2 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 5, 2, 7, 2 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 5, 4, 5, 2 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 7, 4, 7, 2 }, { 2.62531675649206e-09, 3.02224848471497e-10 } }, + { { 3, 6, 5, 2 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 1, 6, 7, 2 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 1, 8, 5, 2 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 3, 8, 7, 2 }, { -2.62531675639996e-09, -3.02224848795605e-10 } }, + { { 5, 2, 5, 4 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 7, 2, 7, 4 }, { 2.62531675649206e-09, 3.02224848471497e-10 } }, + { { 7, 4, 5, 4 }, { -1.24277413513931e-09, 5.61668777968849e-12 } }, + { { 5, 4, 7, 4 }, { -1.24277413513931e-09, 5.61668777968849e-12 } }, + { { 7, 4, 7, 4 }, { 4.12621310432840e-02, 2.99301196790539e-03 } }, + { { 1, 6, 5, 4 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 3, 6, 7, 4 }, { 1.24277413595630e-09, -5.61668436628098e-12 } }, + { { 3, 8, 5, 4 }, { 1.24277413499966e-09, -5.61668780729011e-12 } }, + { { 1, 8, 7, 4 }, { -2.62531674833921e-09, -3.02224836559841e-10 } }, + { { 3, 8, 7, 4 }, { -4.12621310432840e-02, -2.99301196790539e-03 } }, + { { 7, 2, 1, 6 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 5, 2, 3, 6 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 5, 4, 1, 6 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 7, 4, 3, 6 }, { 1.24277413595630e-09, -5.61668436628098e-12 } }, + { { 3, 6, 1, 6 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 1, 6, 3, 6 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 1, 8, 1, 6 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 3, 8, 3, 6 }, { -1.24277413581665e-09, 5.61668439388257e-12 } }, + { { 5, 2, 1, 8 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 7, 2, 3, 8 }, { -2.62531675639996e-09, -3.02224848795605e-10 } }, + { { 7, 4, 1, 8 }, { -2.62531674833921e-09, -3.02224836559841e-10 } }, + { { 5, 4, 3, 8 }, { 1.24277413499966e-09, -5.61668780729011e-12 } }, + { { 7, 4, 3, 8 }, { -4.12621310432840e-02, -2.99301196790539e-03 } }, + { { 1, 6, 1, 8 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 3, 6, 3, 8 }, { -1.24277413581665e-09, 5.61668439388257e-12 } }, + { { 3, 8, 1, 8 }, { 2.62531674824712e-09, 3.02224836883949e-10 } }, + { { 1, 8, 3, 8 }, { 2.62531674824712e-09, 3.02224836883949e-10 } }, + { { 3, 8, 3, 8 }, { 4.12621310432840e-02, 2.99301196790540e-03 } }, + { { 7, 1, 6, 1 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 5, 1, 8, 1 }, { 4.07154504766646e-09, -3.34683209025669e-10 } }, + { { 1, 3, 4, 1 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 5, 3, 8, 1 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 7, 3, 8, 1 }, { 1.49528282810068e-09, 1.95530142616690e-09 } }, + { { 3, 5, 6, 1 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, + { { 1, 5, 8, 1 }, { 3.44264964154066e-09, -9.90113246252263e-12 } }, + { { 5, 7, 4, 1 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 1, 7, 8, 1 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 3, 7, 8, 1 }, { 8.11616423423967e-10, -1.67305274317960e-09 } }, + { { 5, 1, 6, 3 }, { -1.64913548274895e-09, 1.70894051588900e-10 } }, + { { 5, 1, 8, 3 }, { 5.50878617883651e-02, -1.99531994223259e-03 } }, + { { 7, 1, 8, 3 }, { 2.90052566249363e-09, 2.04564331631174e-09 } }, + { { 1, 3, 2, 3 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 5, 3, 6, 3 }, { 2.77775993160252e-04, 3.77410302057860e-03 } }, + { { 5, 3, 8, 3 }, { -4.67622884853612e-09, -6.98952045795709e-10 } }, + { { 7, 3, 8, 3 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 1, 5, 6, 3 }, { -1.76420137101272e-09, -1.05104052115801e-10 } }, + { { 1, 5, 8, 3 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, + { { 3, 5, 8, 3 }, { -4.05111132068935e-09, 1.17669809910942e-09 } }, + { { 5, 7, 2, 3 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 1, 7, 6, 3 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 3, 7, 6, 3 }, { -7.35799849724064e-10, 8.96392999344636e-10 } }, + { { 1, 7, 8, 3 }, { 2.71542765796015e-09, -1.76543336019022e-09 } }, + { { 3, 7, 8, 3 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 7, 1, 2, 5 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 5, 1, 4, 5 }, { 1.64913548399047e-09, -1.70894048294891e-10 } }, + { { 5, 3, 4, 5 }, { -2.77775993160252e-04, -3.77410302057860e-03 } }, + { { 1, 3, 8, 5 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 3, 5, 2, 5 }, { -7.84227887895554e-10, -8.65456802951857e-10 } }, + { { 1, 5, 4, 5 }, { 1.76420137225424e-09, 1.05104055409810e-10 } }, + { { 1, 7, 4, 5 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 3, 7, 4, 5 }, { 7.35799852035404e-10, -8.96392999081955e-10 } }, + { { 5, 7, 8, 5 }, { 2.10829501478453e-03, -9.24701177434335e-03 } }, + { { 5, 1, 2, 7 }, { -4.07154503624496e-09, 3.34683197320015e-10 } }, + { { 5, 1, 4, 7 }, { -5.50878617883651e-02, 1.99531994223258e-03 } }, + { { 7, 1, 4, 7 }, { -2.90052566280734e-09, -2.04564331648436e-09 } }, + { { 5, 3, 2, 7 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 7, 3, 2, 7 }, { -1.49528281775848e-09, -1.95530142301122e-09 } }, + { { 5, 3, 4, 7 }, { 4.67622884828570e-09, 6.98952045491450e-10 } }, + { { 7, 3, 4, 7 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 1, 3, 6, 7 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 1, 5, 2, 7 }, { -3.44264963011916e-09, 9.90112075686836e-12 } }, + { { 1, 5, 4, 7 }, { -5.50878617767860e-02, 1.99532026191666e-03 } }, + { { 3, 5, 4, 7 }, { 4.05111132035920e-09, -1.17669809883779e-09 } }, + { { 1, 7, 2, 7 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 3, 7, 2, 7 }, { -8.11616426840793e-10, 1.67305273292072e-09 } }, + { { 1, 7, 4, 7 }, { -2.71542765827455e-09, 1.76543336029064e-09 } }, + { { 3, 7, 4, 7 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 5, 7, 6, 7 }, { -2.10829501478453e-03, 9.24701177434334e-03 } }, + { { 1, 1, 2, 2 }, { 2.61972936056406e-01, -5.30213028386074e-17 } }, + { { 3, 1, 2, 2 }, { 1.26743997191602e-09, 9.20431351748613e-12 } }, + { { 1, 1, 4, 2 }, { 1.26743997139537e-09, -9.20430897449278e-12 } }, + { { 3, 1, 4, 2 }, { 2.00381403996136e-02, -1.62630325872826e-18 } }, + { { 5, 1, 6, 2 }, { 7.34497110698912e-02, 2.32390791791556e-17 } }, + { { 7, 1, 6, 2 }, { 3.38241175355620e-09, 2.85419828471446e-09 } }, + { { 5, 1, 8, 2 }, { 3.38241175357191e-09, -2.85419828967186e-09 } }, + { { 7, 1, 8, 2 }, { 1.04255386413001e-02, -2.16840434497101e-19 } }, + { { 1, 3, 2, 2 }, { 1.26743996457650e-09, -9.20429928368850e-12 } }, + { { 3, 3, 2, 2 }, { 2.61943485031872e-01, -1.37722265068768e-17 } }, + { { 3, 3, 4, 2 }, { -1.27168924198546e-09, 9.73022871836289e-12 } }, + { { 5, 3, 6, 2 }, { -4.51615803003425e-09, -1.41887387061851e-09 } }, + { { 7, 3, 6, 2 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, + { { 7, 3, 8, 2 }, { 2.15553000777860e-09, 1.31756361465258e-09 } }, + { { 5, 5, 2, 2 }, { 2.50873194689164e-01, 2.50879550989324e-17 } }, + { { 7, 5, 4, 2 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, + { { 1, 5, 6, 2 }, { 7.34497110698911e-02, -4.26240855372007e-10 } }, + { { 3, 5, 6, 2 }, { -5.63030150072833e-09, 1.78997963434557e-09 } }, + { { 1, 5, 8, 2 }, { 4.01669748488940e-09, -3.60591433236876e-09 } }, + { { 3, 5, 8, 2 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 7, 7, 2, 2 }, { 2.50828949907785e-01, -1.14936844391139e-17 } }, + { { 1, 7, 6, 2 }, { 4.01669748357888e-09, -3.60591431101307e-09 } }, + { { 3, 7, 6, 2 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, + { { 3, 7, 8, 2 }, { -4.28392086691139e-10, -3.43537540225082e-09 } }, + { { 1, 1, 2, 4 }, { 1.26743996509614e-09, 9.20431253262051e-12 } }, + { { 1, 1, 4, 4 }, { 2.61943485031872e-01, -1.12169505428259e-17 } }, + { { 3, 1, 4, 4 }, { -1.27168924251628e-09, -9.73022385794241e-12 } }, + { { 5, 1, 6, 4 }, { -4.51615803040078e-09, 1.41887386923595e-09 } }, + { { 5, 1, 8, 4 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 7, 1, 8, 4 }, { 2.15553000456903e-09, -1.31756361634066e-09 } }, + { { 1, 3, 2, 4 }, { 2.00381403996136e-02, -8.67361737988404e-19 } }, + { { 3, 3, 2, 4 }, { -1.27168924954398e-09, -9.73022416051130e-12 } }, + { { 1, 3, 4, 4 }, { -1.27168924901213e-09, 9.73023776236440e-12 } }, + { { 3, 3, 4, 4 }, { 2.61914049687002e-01, 2.80103420724926e-17 } }, + { { 5, 3, 6, 4 }, { 1.48617254260414e-02, -6.50521303491303e-19 } }, + { { 7, 3, 6, 4 }, { -2.00828744436733e-09, -2.74866710690401e-09 } }, + { { 5, 3, 8, 4 }, { -2.00828744455438e-09, 2.74866710694982e-09 } }, + { { 7, 3, 8, 4 }, { 3.20339000240785e-02, -5.20417042793042e-18 } }, + { { 5, 5, 4, 4 }, { 2.50843627819692e-01, 4.72101682017815e-17 } }, + { { 1, 5, 6, 4 }, { -5.63030148921086e-09, 1.78997963244246e-09 } }, + { { 1, 5, 8, 4 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, + { { 3, 5, 8, 4 }, { -1.11475987598887e-09, 4.36237059368112e-09 } }, + { { 5, 7, 2, 4 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 7, 7, 4, 4 }, { 2.50799402750969e-01, 1.06092925530601e-17 } }, + { { 1, 7, 6, 4 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 3, 7, 6, 4 }, { -1.11475987342053e-09, 4.36237058630139e-09 } }, + { { 1, 7, 8, 4 }, { -4.28392074239289e-10, -3.43537539464995e-09 } }, + { { 3, 7, 8, 4 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, + { { 5, 1, 2, 6 }, { 7.34497110698911e-02, 4.26240884128866e-10 } }, + { { 7, 1, 2, 6 }, { 4.01669748523631e-09, 3.60591432791919e-09 } }, + { { 5, 1, 4, 6 }, { -5.63030150036024e-09, -1.78997964461309e-09 } }, + { { 7, 1, 4, 6 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 1, 1, 6, 6 }, { 2.50873194689164e-01, -3.87204018911796e-18 } }, + { { 3, 1, 8, 6 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 5, 3, 2, 6 }, { -5.63030148956796e-09, -1.78997963400265e-09 } }, + { { 7, 3, 2, 6 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, + { { 7, 3, 4, 6 }, { -1.11475986949617e-09, -4.36237059634356e-09 } }, + { { 3, 3, 6, 6 }, { 2.50843627819692e-01, 1.72941652301881e-17 } }, + { { 1, 5, 2, 6 }, { 7.34497110698912e-02, 5.51778003395311e-18 } }, + { { 3, 5, 2, 6 }, { -4.51615804182034e-09, 1.41887387030459e-09 } }, + { { 1, 5, 4, 6 }, { -4.51615804217584e-09, -1.41887388074977e-09 } }, + { { 3, 5, 4, 6 }, { 1.48617254260414e-02, -1.84314369322536e-18 } }, + { { 5, 5, 6, 6 }, { 2.46623945475382e-01, -4.47440139398777e-18 } }, + { { 7, 5, 8, 6 }, { 1.31792902727351e-02, 4.87890977618477e-19 } }, + { { 1, 7, 2, 6 }, { 3.38241175221570e-09, -2.85419826711785e-09 } }, + { { 3, 7, 2, 6 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 3, 7, 4, 6 }, { -2.00828745395385e-09, 2.74866711051040e-09 } }, + { { 7, 7, 6, 6 }, { 2.46582791504814e-01, -4.25634912984626e-18 } }, + { { 5, 1, 2, 8 }, { 4.01669748356451e-09, 3.60591430698319e-09 } }, + { { 5, 1, 4, 8 }, { 2.22515327441311e-02, 4.31016204922364e-02 } }, + { { 7, 1, 4, 8 }, { -4.28392084504226e-10, 3.43537540051425e-09 } }, + { { 1, 1, 8, 8 }, { 2.50828949907785e-01, -1.24613051726560e-17 } }, + { { 5, 3, 2, 8 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 7, 3, 2, 8 }, { -4.28392072544871e-10, 3.43537539324139e-09 } }, + { { 5, 3, 4, 8 }, { -1.11475987210074e-09, -4.36237058622425e-09 } }, + { { 7, 3, 4, 8 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, + { { 1, 3, 6, 8 }, { 5.62113152593797e-03, 1.41002713662608e-02 } }, + { { 3, 3, 8, 8 }, { 2.50799402750969e-01, 8.69850171916772e-18 } }, + { { 1, 5, 2, 8 }, { 3.38241175256395e-09, 2.85419826359582e-09 } }, + { { 1, 5, 4, 8 }, { 2.22515329942571e-02, 4.31016203631070e-02 } }, + { { 3, 5, 4, 8 }, { -2.00828744859485e-09, -2.74866711314251e-09 } }, + { { 5, 5, 8, 8 }, { 2.46582791504814e-01, 5.87188339049711e-18 } }, + { { 1, 7, 2, 8 }, { 1.04255386413001e-02, 7.58941520739853e-19 } }, + { { 3, 7, 2, 8 }, { 2.15552999194172e-09, -1.31756362203174e-09 } }, + { { 1, 7, 4, 8 }, { 2.15552999465798e-09, 1.31756362057390e-09 } }, + { { 3, 7, 4, 8 }, { 3.20339000240785e-02, -1.73472347597681e-18 } }, + { { 5, 7, 6, 8 }, { 1.31792902727351e-02, -9.21571846612679e-19 } }, + { { 7, 7, 8, 8 }, { 2.46541664704192e-01, 6.08293979259109e-18 } }, + { { 3, 2, 4, 1 }, { -1.29929463938391e-03, 2.71050543121376e-20 } }, + { { 5, 2, 6, 1 }, { -6.12304508882666e-08, -3.19152887970202e-24 } }, + { { 7, 2, 8, 1 }, { -5.39920423655626e-03, 2.16840434497101e-19 } }, + { { 1, 4, 4, 1 }, { 1.29929463938391e-03, 2.03287907341032e-20 } }, + { { 5, 4, 8, 1 }, { 1.86176220289677e-04, 2.27333215595726e-03 } }, + { { 7, 4, 8, 1 }, { -2.29550213538554e-09, 1.68336752118145e-10 } }, + { { 7, 6, 4, 1 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 1, 6, 6, 1 }, { 6.12304508882666e-08, 1.79308951503732e-24 } }, + { { 3, 6, 8, 1 }, { -1.86176220289677e-04, -2.27333215595726e-03 } }, + { { 5, 8, 4, 1 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 1, 8, 8, 1 }, { 5.39920423655626e-03, -3.79470760369927e-19 } }, + { { 3, 8, 8, 1 }, { 2.29550213550629e-09, -1.68336752322676e-10 } }, + { { 3, 2, 2, 3 }, { 1.29929463938391e-03, 6.77626357803440e-20 } }, + { { 7, 2, 6, 3 }, { 1.86176220289677e-04, -2.27333215595725e-03 } }, + { { 7, 2, 8, 3 }, { -2.29550213630685e-09, -1.68336776816198e-10 } }, + { { 1, 4, 2, 3 }, { -1.29929463938391e-03, -7.45388993583784e-20 } }, + { { 5, 4, 6, 3 }, { -9.63632834913280e-04, 3.38813178901720e-20 } }, + { { 7, 4, 6, 3 }, { 1.20329000661327e-09, 2.38730244045649e-10 } }, + { { 5, 4, 8, 3 }, { 1.20329000658700e-09, -2.38730245117277e-10 } }, + { { 7, 4, 8, 3 }, { -4.13705399893557e-02, -4.33680868994202e-19 } }, + { { 7, 6, 2, 3 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 3, 6, 6, 3 }, { 9.63632834913280e-04, -4.74338450462408e-20 } }, + { { 3, 6, 8, 3 }, { -1.20329000743663e-09, 2.38730247620597e-10 } }, + { { 5, 8, 2, 3 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 1, 8, 6, 3 }, { -1.86176220289677e-04, 2.27333215595725e-03 } }, + { { 3, 8, 6, 3 }, { -1.20329000653132e-09, -2.38730243987742e-10 } }, + { { 1, 8, 8, 3 }, { 2.29550212741584e-09, 1.68336768334048e-10 } }, + { { 3, 8, 8, 3 }, { 4.13705399893557e-02, -9.10729824887824e-18 } }, + { { 5, 2, 2, 5 }, { 6.12304508882665e-08, 8.76752829052342e-25 } }, + { { 7, 2, 4, 5 }, { -1.86176220289677e-04, 2.27333215595725e-03 } }, + { { 3, 2, 8, 5 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 5, 4, 4, 5 }, { 9.63632834913280e-04, 2.03287907341032e-20 } }, + { { 7, 4, 4, 5 }, { -1.20329000767507e-09, -2.38730240700292e-10 } }, + { { 1, 4, 8, 5 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 1, 6, 2, 5 }, { -6.12304508882665e-08, 5.21686141181912e-25 } }, + { { 3, 6, 4, 5 }, { -9.63632834913280e-04, 1.35525271560688e-20 } }, + { { 7, 6, 8, 5 }, { -6.82529157237476e-03, 1.08420217248550e-19 } }, + { { 1, 8, 4, 5 }, { 1.86176220289677e-04, -2.27333215595725e-03 } }, + { { 3, 8, 4, 5 }, { 1.20329000759312e-09, 2.38730240642386e-10 } }, + { { 5, 8, 8, 5 }, { 6.82529157237476e-03, 2.71050543121376e-19 } }, + { { 7, 2, 2, 7 }, { 5.39920423655626e-03, -0.00000000000000e+00 } }, + { { 7, 2, 4, 7 }, { 2.29550213669100e-09, 1.68336776889122e-10 } }, + { { 3, 2, 6, 7 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 5, 4, 2, 7 }, { -1.86176220289677e-04, -2.27333215595725e-03 } }, + { { 7, 4, 2, 7 }, { 2.29550212639229e-09, -1.68336740827533e-10 } }, + { { 5, 4, 4, 7 }, { -1.20329000656955e-09, 2.38730244953007e-10 } }, + { { 7, 4, 4, 7 }, { 4.13705399893557e-02, -3.25260651745651e-18 } }, + { { 1, 4, 6, 7 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 3, 6, 2, 7 }, { 1.86176220289677e-04, 2.27333215595725e-03 } }, + { { 3, 6, 4, 7 }, { 1.20329000741918e-09, -2.38730247456327e-10 } }, + { { 7, 6, 6, 7 }, { 6.82529157237476e-03, -4.87890977618477e-19 } }, + { { 1, 8, 2, 7 }, { -5.39920423655626e-03, 2.16840434497101e-19 } }, + { { 3, 8, 2, 7 }, { -2.29550212651305e-09, 1.68336741032063e-10 } }, + { { 1, 8, 4, 7 }, { -2.29550212779999e-09, -1.68336768406972e-10 } }, + { { 3, 8, 4, 7 }, { -4.13705399893557e-02, 1.23599047663348e-17 } }, + { { 5, 8, 6, 7 }, { -6.82529157237476e-03, -5.42101086242752e-20 } }, + { { 7, 2, 6, 2 }, { -4.07154503617311e-09, -3.34683197652399e-10 } }, + { { 5, 2, 8, 2 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 5, 4, 6, 2 }, { 1.64913548384803e-09, 1.70894048276102e-10 } }, + { { 7, 4, 6, 2 }, { -5.50878617883651e-02, -1.99531994223259e-03 } }, + { { 7, 4, 8, 2 }, { -2.90052566130477e-09, 2.04564330064451e-09 } }, + { { 3, 6, 6, 2 }, { -1.64913548260651e-09, -1.70894051570111e-10 } }, + { { 1, 6, 8, 2 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 1, 8, 6, 2 }, { 4.07154504759461e-09, 3.34683209358053e-10 } }, + { { 3, 8, 6, 2 }, { 5.50878617883651e-02, 1.99531994223260e-03 } }, + { { 3, 8, 8, 2 }, { 2.90052566099105e-09, -2.04564330047190e-09 } }, + { { 3, 2, 2, 4 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 7, 2, 6, 4 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 7, 2, 8, 4 }, { -1.49528281786713e-09, 1.95530142297282e-09 } }, + { { 1, 4, 2, 4 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 5, 4, 6, 4 }, { -2.77775993160253e-04, 3.77410302057860e-03 } }, + { { 7, 4, 6, 4 }, { 4.67622885713219e-09, -6.98952053111356e-10 } }, + { { 7, 4, 8, 4 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 7, 6, 2, 4 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 3, 6, 6, 4 }, { 2.77775993160253e-04, -3.77410302057860e-03 } }, + { { 5, 8, 2, 4 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 1, 8, 6, 4 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 3, 8, 6, 4 }, { -4.67622885738260e-09, 6.98952053415614e-10 } }, + { { 1, 8, 8, 4 }, { 1.49528282820932e-09, -1.95530142612850e-09 } }, + { { 3, 8, 8, 4 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 7, 2, 2, 6 }, { -3.44264963006675e-09, -9.90112058323764e-12 } }, + { { 5, 2, 4, 6 }, { -7.84227887895553e-10, 8.65456802951857e-10 } }, + { { 5, 4, 2, 6 }, { 1.76420137232554e-09, -1.05104055437868e-10 } }, + { { 7, 4, 2, 6 }, { -5.50878617767860e-02, -1.99532026191665e-03 } }, + { { 7, 4, 4, 6 }, { 4.05111131184309e-09, 1.17669809730382e-09 } }, + { { 3, 6, 2, 6 }, { -1.76420137108402e-09, 1.05104052143859e-10 } }, + { { 1, 6, 4, 6 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, + { { 1, 8, 2, 6 }, { 3.44264964148825e-09, 9.90113228889187e-12 } }, + { { 3, 8, 2, 6 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, + { { 3, 8, 4, 6 }, { -4.05111131217324e-09, -1.17669809757545e-09 } }, + { { 7, 2, 2, 8 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 7, 2, 4, 8 }, { -8.11616426817687e-10, -1.67305273280271e-09 } }, + { { 3, 2, 6, 8 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 5, 4, 2, 8 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 7, 4, 2, 8 }, { -2.71542765860322e-09, -1.76543337688875e-09 } }, + { { 5, 4, 4, 8 }, { 7.35799852084301e-10, 8.96392999068158e-10 } }, + { { 7, 4, 4, 8 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 1, 4, 6, 8 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 3, 6, 2, 8 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 3, 6, 4, 8 }, { -7.35799849772961e-10, -8.96392999330838e-10 } }, + { { 7, 6, 6, 8 }, { -2.10829501478453e-03, -9.24701177434335e-03 } }, + { { 1, 8, 2, 8 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 3, 8, 2, 8 }, { 2.71542765828882e-09, 1.76543337678833e-09 } }, + { { 1, 8, 4, 8 }, { 8.11616423400861e-10, 1.67305274306159e-09 } }, + { { 3, 8, 4, 8 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 5, 8, 6, 8 }, { 2.10829501478453e-03, 9.24701177434334e-03 } }, + { { 8, 1, 5, 1 }, { 4.07154504766646e-09, -3.34683209025669e-10 } }, + { { 6, 1, 7, 1 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 6, 3, 5, 1 }, { -1.64913548274895e-09, 1.70894051588900e-10 } }, + { { 8, 3, 5, 1 }, { 5.50878617883651e-02, -1.99531994223259e-03 } }, + { { 8, 3, 7, 1 }, { 2.90052566249363e-09, 2.04564331631174e-09 } }, + { { 4, 5, 5, 1 }, { 1.64913548399047e-09, -1.70894048294891e-10 } }, + { { 2, 5, 7, 1 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 2, 7, 5, 1 }, { -4.07154503624496e-09, 3.34683197320015e-10 } }, + { { 4, 7, 5, 1 }, { -5.50878617883651e-02, 1.99531994223258e-03 } }, + { { 4, 7, 7, 1 }, { -2.90052566280734e-09, -2.04564331648436e-09 } }, + { { 4, 1, 1, 3 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 8, 1, 5, 3 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 8, 1, 7, 3 }, { 1.49528282810068e-09, 1.95530142616690e-09 } }, + { { 2, 3, 1, 3 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 6, 3, 5, 3 }, { 2.77775993160252e-04, 3.77410302057860e-03 } }, + { { 8, 3, 5, 3 }, { -4.67622884853612e-09, -6.98952045795709e-10 } }, + { { 8, 3, 7, 3 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 8, 5, 1, 3 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 4, 5, 5, 3 }, { -2.77775993160252e-04, -3.77410302057860e-03 } }, + { { 6, 7, 1, 3 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 2, 7, 5, 3 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 4, 7, 5, 3 }, { 4.67622884828570e-09, 6.98952045491450e-10 } }, + { { 2, 7, 7, 3 }, { -1.49528281775848e-09, -1.95530142301122e-09 } }, + { { 4, 7, 7, 3 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 8, 1, 1, 5 }, { 3.44264964154066e-09, -9.90113246252263e-12 } }, + { { 6, 1, 3, 5 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, + { { 6, 3, 1, 5 }, { -1.76420137101272e-09, -1.05104052115801e-10 } }, + { { 8, 3, 1, 5 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, + { { 8, 3, 3, 5 }, { -4.05111132068935e-09, 1.17669809910942e-09 } }, + { { 4, 5, 1, 5 }, { 1.76420137225424e-09, 1.05104055409810e-10 } }, + { { 2, 5, 3, 5 }, { -7.84227887895554e-10, -8.65456802951857e-10 } }, + { { 2, 7, 1, 5 }, { -3.44264963011916e-09, 9.90112075686836e-12 } }, + { { 4, 7, 1, 5 }, { -5.50878617767860e-02, 1.99532026191666e-03 } }, + { { 4, 7, 3, 5 }, { 4.05111132035920e-09, -1.17669809883779e-09 } }, + { { 8, 1, 1, 7 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 8, 1, 3, 7 }, { 8.11616423423967e-10, -1.67305274317960e-09 } }, + { { 4, 1, 5, 7 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 6, 3, 1, 7 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 8, 3, 1, 7 }, { 2.71542765796015e-09, -1.76543336019022e-09 } }, + { { 6, 3, 3, 7 }, { -7.35799849724064e-10, 8.96392999344636e-10 } }, + { { 8, 3, 3, 7 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 2, 3, 5, 7 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 4, 5, 1, 7 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 4, 5, 3, 7 }, { 7.35799852035404e-10, -8.96392999081955e-10 } }, + { { 8, 5, 5, 7 }, { 2.10829501478453e-03, -9.24701177434335e-03 } }, + { { 2, 7, 1, 7 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 4, 7, 1, 7 }, { -2.71542765827455e-09, 1.76543336029064e-09 } }, + { { 2, 7, 3, 7 }, { -8.11616426840793e-10, 1.67305273292072e-09 } }, + { { 4, 7, 3, 7 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 6, 7, 5, 7 }, { -2.10829501478453e-03, 9.24701177434334e-03 } }, + { { 4, 1, 3, 2 }, { -1.29929463938391e-03, -2.71050543121376e-20 } }, + { { 6, 1, 5, 2 }, { -6.12304508882666e-08, 3.19152887970202e-24 } }, + { { 8, 1, 7, 2 }, { -5.39920423655626e-03, -2.16840434497101e-19 } }, + { { 2, 3, 3, 2 }, { 1.29929463938391e-03, -2.03287907341032e-20 } }, + { { 6, 3, 7, 2 }, { 1.86176220289677e-04, -2.27333215595726e-03 } }, + { { 8, 3, 7, 2 }, { -2.29550213538554e-09, -1.68336752118145e-10 } }, + { { 8, 5, 3, 2 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 2, 5, 5, 2 }, { 6.12304508882666e-08, -1.79308951503732e-24 } }, + { { 4, 5, 7, 2 }, { -1.86176220289677e-04, 2.27333215595726e-03 } }, + { { 6, 7, 3, 2 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 2, 7, 7, 2 }, { 5.39920423655626e-03, 3.79470760369927e-19 } }, + { { 4, 7, 7, 2 }, { 2.29550213550629e-09, 1.68336752322676e-10 } }, + { { 4, 1, 1, 4 }, { 1.29929463938391e-03, -6.77626357803440e-20 } }, + { { 8, 1, 5, 4 }, { 1.86176220289677e-04, 2.27333215595725e-03 } }, + { { 8, 1, 7, 4 }, { -2.29550213630685e-09, 1.68336776816198e-10 } }, + { { 2, 3, 1, 4 }, { -1.29929463938391e-03, 7.45388993583784e-20 } }, + { { 6, 3, 5, 4 }, { -9.63632834913280e-04, -3.38813178901720e-20 } }, + { { 8, 3, 5, 4 }, { 1.20329000661327e-09, -2.38730244045649e-10 } }, + { { 6, 3, 7, 4 }, { 1.20329000658700e-09, 2.38730245117277e-10 } }, + { { 8, 3, 7, 4 }, { -4.13705399893557e-02, 4.33680868994202e-19 } }, + { { 8, 5, 1, 4 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 4, 5, 5, 4 }, { 9.63632834913280e-04, 4.74338450462408e-20 } }, + { { 4, 5, 7, 4 }, { -1.20329000743663e-09, -2.38730247620597e-10 } }, + { { 6, 7, 1, 4 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 2, 7, 5, 4 }, { -1.86176220289677e-04, -2.27333215595725e-03 } }, + { { 4, 7, 5, 4 }, { -1.20329000653132e-09, 2.38730243987742e-10 } }, + { { 2, 7, 7, 4 }, { 2.29550212741584e-09, -1.68336768334048e-10 } }, + { { 4, 7, 7, 4 }, { 4.13705399893557e-02, 9.10729824887824e-18 } }, + { { 6, 1, 1, 6 }, { 6.12304508882665e-08, -8.76752829052342e-25 } }, + { { 8, 1, 3, 6 }, { -1.86176220289677e-04, -2.27333215595725e-03 } }, + { { 4, 1, 7, 6 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 6, 3, 3, 6 }, { 9.63632834913280e-04, -2.03287907341032e-20 } }, + { { 8, 3, 3, 6 }, { -1.20329000767507e-09, 2.38730240700292e-10 } }, + { { 2, 3, 7, 6 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 2, 5, 1, 6 }, { -6.12304508882665e-08, -5.21686141181912e-25 } }, + { { 4, 5, 3, 6 }, { -9.63632834913280e-04, -1.35525271560688e-20 } }, + { { 8, 5, 7, 6 }, { -6.82529157237476e-03, -1.08420217248550e-19 } }, + { { 2, 7, 3, 6 }, { 1.86176220289677e-04, 2.27333215595725e-03 } }, + { { 4, 7, 3, 6 }, { 1.20329000759312e-09, -2.38730240642386e-10 } }, + { { 6, 7, 7, 6 }, { 6.82529157237476e-03, -2.71050543121376e-19 } }, + { { 8, 1, 1, 8 }, { 5.39920423655626e-03, 0.00000000000000e+00 } }, + { { 8, 1, 3, 8 }, { 2.29550213669100e-09, -1.68336776889122e-10 } }, + { { 4, 1, 5, 8 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, + { { 6, 3, 1, 8 }, { -1.86176220289677e-04, 2.27333215595725e-03 } }, + { { 8, 3, 1, 8 }, { 2.29550212639229e-09, 1.68336740827533e-10 } }, + { { 6, 3, 3, 8 }, { -1.20329000656955e-09, -2.38730244953007e-10 } }, + { { 8, 3, 3, 8 }, { 4.13705399893557e-02, 3.25260651745651e-18 } }, + { { 2, 3, 5, 8 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, + { { 4, 5, 1, 8 }, { 1.86176220289677e-04, -2.27333215595725e-03 } }, + { { 4, 5, 3, 8 }, { 1.20329000741918e-09, 2.38730247456327e-10 } }, + { { 8, 5, 5, 8 }, { 6.82529157237476e-03, 4.87890977618477e-19 } }, + { { 2, 7, 1, 8 }, { -5.39920423655626e-03, -2.16840434497101e-19 } }, + { { 4, 7, 1, 8 }, { -2.29550212651305e-09, -1.68336741032063e-10 } }, + { { 2, 7, 3, 8 }, { -2.29550212779999e-09, 1.68336768406972e-10 } }, + { { 4, 7, 3, 8 }, { -4.13705399893557e-02, -1.23599047663348e-17 } }, + { { 6, 7, 5, 8 }, { -6.82529157237476e-03, 5.42101086242752e-20 } }, + { { 2, 2, 1, 1 }, { 2.61972936056406e-01, 5.30213028386074e-17 } }, + { { 4, 2, 1, 1 }, { 1.26743997191602e-09, -9.20431351748613e-12 } }, + { { 2, 2, 3, 1 }, { 1.26743997139537e-09, 9.20430897449278e-12 } }, + { { 4, 2, 3, 1 }, { 2.00381403996136e-02, 1.62630325872826e-18 } }, + { { 6, 2, 5, 1 }, { 7.34497110698912e-02, -2.32390791791556e-17 } }, + { { 8, 2, 5, 1 }, { 3.38241175355620e-09, -2.85419828471446e-09 } }, + { { 6, 2, 7, 1 }, { 3.38241175357191e-09, 2.85419828967186e-09 } }, + { { 8, 2, 7, 1 }, { 1.04255386413001e-02, 2.16840434497101e-19 } }, + { { 2, 4, 1, 1 }, { 1.26743996457650e-09, 9.20429928368850e-12 } }, + { { 4, 4, 1, 1 }, { 2.61943485031872e-01, 1.37722265068768e-17 } }, + { { 4, 4, 3, 1 }, { -1.27168924198546e-09, -9.73022871836289e-12 } }, + { { 6, 4, 5, 1 }, { -4.51615803003425e-09, 1.41887387061851e-09 } }, + { { 8, 4, 5, 1 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 8, 4, 7, 1 }, { 2.15553000777860e-09, -1.31756361465258e-09 } }, + { { 6, 6, 1, 1 }, { 2.50873194689164e-01, -2.50879550989324e-17 } }, + { { 8, 6, 3, 1 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 2, 6, 5, 1 }, { 7.34497110698911e-02, 4.26240855372007e-10 } }, + { { 4, 6, 5, 1 }, { -5.63030150072833e-09, -1.78997963434557e-09 } }, + { { 2, 6, 7, 1 }, { 4.01669748488940e-09, 3.60591433236876e-09 } }, + { { 4, 6, 7, 1 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 8, 8, 1, 1 }, { 2.50828949907785e-01, 1.14936844391139e-17 } }, + { { 2, 8, 5, 1 }, { 4.01669748357888e-09, 3.60591431101307e-09 } }, + { { 4, 8, 5, 1 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, + { { 4, 8, 7, 1 }, { -4.28392086691139e-10, 3.43537540225082e-09 } }, + { { 2, 2, 1, 3 }, { 1.26743996509614e-09, -9.20431253262051e-12 } }, + { { 2, 2, 3, 3 }, { 2.61943485031872e-01, 1.12169505428259e-17 } }, + { { 4, 2, 3, 3 }, { -1.27168924251628e-09, 9.73022385794241e-12 } }, + { { 6, 2, 5, 3 }, { -4.51615803040078e-09, -1.41887386923595e-09 } }, + { { 6, 2, 7, 3 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, + { { 8, 2, 7, 3 }, { 2.15553000456903e-09, 1.31756361634066e-09 } }, + { { 2, 4, 1, 3 }, { 2.00381403996136e-02, 8.67361737988404e-19 } }, + { { 4, 4, 1, 3 }, { -1.27168924954398e-09, 9.73022416051130e-12 } }, + { { 2, 4, 3, 3 }, { -1.27168924901213e-09, -9.73023776236440e-12 } }, + { { 4, 4, 3, 3 }, { 2.61914049687002e-01, -2.80103420724926e-17 } }, + { { 6, 4, 5, 3 }, { 1.48617254260414e-02, 6.50521303491303e-19 } }, + { { 8, 4, 5, 3 }, { -2.00828744436733e-09, 2.74866710690401e-09 } }, + { { 6, 4, 7, 3 }, { -2.00828744455438e-09, -2.74866710694982e-09 } }, + { { 8, 4, 7, 3 }, { 3.20339000240785e-02, 5.20417042793042e-18 } }, + { { 6, 6, 3, 3 }, { 2.50843627819692e-01, -4.72101682017815e-17 } }, + { { 2, 6, 5, 3 }, { -5.63030148921086e-09, -1.78997963244246e-09 } }, + { { 2, 6, 7, 3 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, + { { 4, 6, 7, 3 }, { -1.11475987598887e-09, -4.36237059368112e-09 } }, + { { 6, 8, 1, 3 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, + { { 8, 8, 3, 3 }, { 2.50799402750969e-01, -1.06092925530601e-17 } }, + { { 2, 8, 5, 3 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 4, 8, 5, 3 }, { -1.11475987342053e-09, -4.36237058630139e-09 } }, + { { 2, 8, 7, 3 }, { -4.28392074239289e-10, 3.43537539464995e-09 } }, + { { 4, 8, 7, 3 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, + { { 6, 2, 1, 5 }, { 7.34497110698911e-02, -4.26240884128866e-10 } }, + { { 8, 2, 1, 5 }, { 4.01669748523631e-09, -3.60591432791919e-09 } }, + { { 6, 2, 3, 5 }, { -5.63030150036024e-09, 1.78997964461309e-09 } }, + { { 8, 2, 3, 5 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 2, 2, 5, 5 }, { 2.50873194689164e-01, 3.87204018911796e-18 } }, + { { 4, 2, 7, 5 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, + { { 6, 4, 1, 5 }, { -5.63030148956796e-09, 1.78997963400265e-09 } }, + { { 8, 4, 1, 5 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, + { { 8, 4, 3, 5 }, { -1.11475986949617e-09, 4.36237059634356e-09 } }, + { { 4, 4, 5, 5 }, { 2.50843627819692e-01, -1.72941652301881e-17 } }, + { { 2, 6, 1, 5 }, { 7.34497110698912e-02, -5.51778003395311e-18 } }, + { { 4, 6, 1, 5 }, { -4.51615804182034e-09, -1.41887387030459e-09 } }, + { { 2, 6, 3, 5 }, { -4.51615804217584e-09, 1.41887388074977e-09 } }, + { { 4, 6, 3, 5 }, { 1.48617254260414e-02, 1.84314369322536e-18 } }, + { { 6, 6, 5, 5 }, { 2.46623945475382e-01, 4.47440139398777e-18 } }, + { { 8, 6, 7, 5 }, { 1.31792902727351e-02, -4.87890977618477e-19 } }, + { { 2, 8, 1, 5 }, { 3.38241175221570e-09, 2.85419826711785e-09 } }, + { { 4, 8, 1, 5 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, + { { 4, 8, 3, 5 }, { -2.00828745395385e-09, -2.74866711051040e-09 } }, + { { 8, 8, 5, 5 }, { 2.46582791504814e-01, 4.25634912984626e-18 } }, + { { 6, 2, 1, 7 }, { 4.01669748356451e-09, -3.60591430698319e-09 } }, + { { 6, 2, 3, 7 }, { 2.22515327441311e-02, -4.31016204922364e-02 } }, + { { 8, 2, 3, 7 }, { -4.28392084504226e-10, -3.43537540051425e-09 } }, + { { 2, 2, 7, 7 }, { 2.50828949907785e-01, 1.24613051726560e-17 } }, + { { 6, 4, 1, 7 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 8, 4, 1, 7 }, { -4.28392072544871e-10, -3.43537539324139e-09 } }, + { { 6, 4, 3, 7 }, { -1.11475987210074e-09, 4.36237058622425e-09 } }, + { { 8, 4, 3, 7 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, + { { 2, 4, 5, 7 }, { 5.62113152593797e-03, -1.41002713662608e-02 } }, + { { 4, 4, 7, 7 }, { 2.50799402750969e-01, -8.69850171916772e-18 } }, + { { 2, 6, 1, 7 }, { 3.38241175256395e-09, -2.85419826359582e-09 } }, + { { 2, 6, 3, 7 }, { 2.22515329942571e-02, -4.31016203631070e-02 } }, + { { 4, 6, 3, 7 }, { -2.00828744859485e-09, 2.74866711314251e-09 } }, + { { 6, 6, 7, 7 }, { 2.46582791504814e-01, -5.87188339049711e-18 } }, + { { 2, 8, 1, 7 }, { 1.04255386413001e-02, -7.58941520739853e-19 } }, + { { 4, 8, 1, 7 }, { 2.15552999194172e-09, 1.31756362203174e-09 } }, + { { 2, 8, 3, 7 }, { 2.15552999465798e-09, -1.31756362057390e-09 } }, + { { 4, 8, 3, 7 }, { 3.20339000240785e-02, 1.73472347597681e-18 } }, + { { 6, 8, 5, 7 }, { 1.31792902727351e-02, 9.21571846612679e-19 } }, + { { 8, 8, 7, 7 }, { 2.46541664704192e-01, -6.08293979259109e-18 } }, + { { 8, 2, 5, 2 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 6, 2, 7, 2 }, { -4.07154503617311e-09, -3.34683197652399e-10 } }, + { { 2, 4, 3, 2 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 6, 4, 7, 2 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 8, 4, 7, 2 }, { -1.49528281786713e-09, 1.95530142297282e-09 } }, + { { 4, 6, 5, 2 }, { -7.84227887895553e-10, 8.65456802951857e-10 } }, + { { 2, 6, 7, 2 }, { -3.44264963006675e-09, -9.90112058323764e-12 } }, + { { 6, 8, 3, 2 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 2, 8, 7, 2 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 4, 8, 7, 2 }, { -8.11616426817687e-10, -1.67305273280271e-09 } }, + { { 6, 2, 5, 4 }, { 1.64913548384803e-09, 1.70894048276102e-10 } }, + { { 6, 2, 7, 4 }, { -5.50878617883651e-02, -1.99531994223259e-03 } }, + { { 8, 2, 7, 4 }, { -2.90052566130477e-09, 2.04564330064451e-09 } }, + { { 2, 4, 1, 4 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 6, 4, 5, 4 }, { -2.77775993160253e-04, 3.77410302057860e-03 } }, + { { 6, 4, 7, 4 }, { 4.67622885713219e-09, -6.98952053111356e-10 } }, + { { 8, 4, 7, 4 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 2, 6, 5, 4 }, { 1.76420137232554e-09, -1.05104055437868e-10 } }, + { { 2, 6, 7, 4 }, { -5.50878617767860e-02, -1.99532026191665e-03 } }, + { { 4, 6, 7, 4 }, { 4.05111131184309e-09, 1.17669809730382e-09 } }, + { { 6, 8, 1, 4 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 2, 8, 5, 4 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 4, 8, 5, 4 }, { 7.35799852084301e-10, 8.96392999068158e-10 } }, + { { 2, 8, 7, 4 }, { -2.71542765860322e-09, -1.76543337688875e-09 } }, + { { 4, 8, 7, 4 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 8, 2, 1, 6 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 6, 2, 3, 6 }, { -1.64913548260651e-09, -1.70894051570111e-10 } }, + { { 6, 4, 3, 6 }, { 2.77775993160253e-04, -3.77410302057860e-03 } }, + { { 2, 4, 7, 6 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 4, 6, 1, 6 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, + { { 2, 6, 3, 6 }, { -1.76420137108402e-09, 1.05104052143859e-10 } }, + { { 2, 8, 3, 6 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 4, 8, 3, 6 }, { -7.35799849772961e-10, -8.96392999330838e-10 } }, + { { 6, 8, 7, 6 }, { -2.10829501478453e-03, -9.24701177434335e-03 } }, + { { 6, 2, 1, 8 }, { 4.07154504759461e-09, 3.34683209358053e-10 } }, + { { 6, 2, 3, 8 }, { 5.50878617883651e-02, 1.99531994223260e-03 } }, + { { 8, 2, 3, 8 }, { 2.90052566099105e-09, -2.04564330047190e-09 } }, + { { 6, 4, 1, 8 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 8, 4, 1, 8 }, { 1.49528282820932e-09, -1.95530142612850e-09 } }, + { { 6, 4, 3, 8 }, { -4.67622885738260e-09, 6.98952053415614e-10 } }, + { { 8, 4, 3, 8 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 2, 4, 5, 8 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 2, 6, 1, 8 }, { 3.44264964148825e-09, 9.90113228889187e-12 } }, + { { 2, 6, 3, 8 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, + { { 4, 6, 3, 8 }, { -4.05111131217324e-09, -1.17669809757545e-09 } }, + { { 2, 8, 1, 8 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 4, 8, 1, 8 }, { 8.11616423400861e-10, 1.67305274306159e-09 } }, + { { 2, 8, 3, 8 }, { 2.71542765828882e-09, 1.76543337678833e-09 } }, + { { 4, 8, 3, 8 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 6, 8, 5, 8 }, { 2.10829501478453e-03, 9.24701177434334e-03 } }, + { { 8, 1, 6, 1 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 6, 1, 8, 1 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 6, 3, 6, 1 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 8, 3, 8, 1 }, { 2.62531674824712e-09, -3.02224836883949e-10 } }, + { { 4, 5, 6, 1 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 2, 5, 8, 1 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 2, 7, 6, 1 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 4, 7, 8, 1 }, { -2.62531674833921e-09, 3.02224836559841e-10 } }, + { { 6, 1, 6, 3 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 8, 1, 8, 3 }, { 2.62531674824712e-09, -3.02224836883949e-10 } }, + { { 8, 3, 6, 3 }, { -1.24277413581665e-09, -5.61668439388257e-12 } }, + { { 6, 3, 8, 3 }, { -1.24277413581665e-09, -5.61668439388257e-12 } }, + { { 8, 3, 8, 3 }, { 4.12621310432840e-02, -2.99301196790540e-03 } }, + { { 2, 5, 6, 3 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 4, 5, 8, 3 }, { 1.24277413499966e-09, 5.61668780729011e-12 } }, + { { 4, 7, 6, 3 }, { 1.24277413595630e-09, 5.61668436628098e-12 } }, + { { 2, 7, 8, 3 }, { -2.62531675639996e-09, 3.02224848795605e-10 } }, + { { 4, 7, 8, 3 }, { -4.12621310432840e-02, 2.99301196790539e-03 } }, + { { 8, 1, 2, 5 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 6, 1, 4, 5 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 6, 3, 2, 5 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, + { { 8, 3, 4, 5 }, { 1.24277413499966e-09, 5.61668780729011e-12 } }, + { { 4, 5, 2, 5 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 2, 5, 4, 5 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, + { { 2, 7, 2, 5 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 4, 7, 4, 5 }, { -1.24277413513931e-09, -5.61668777968849e-12 } }, + { { 6, 1, 2, 7 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, + { { 8, 1, 4, 7 }, { -2.62531674833921e-09, 3.02224836559841e-10 } }, + { { 8, 3, 2, 7 }, { -2.62531675639996e-09, 3.02224848795605e-10 } }, + { { 6, 3, 4, 7 }, { 1.24277413595630e-09, 5.61668436628098e-12 } }, + { { 8, 3, 4, 7 }, { -4.12621310432840e-02, 2.99301196790539e-03 } }, + { { 2, 5, 2, 7 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, + { { 4, 5, 4, 7 }, { -1.24277413513931e-09, -5.61668777968849e-12 } }, + { { 4, 7, 2, 7 }, { 2.62531675649206e-09, -3.02224848471497e-10 } }, + { { 2, 7, 4, 7 }, { 2.62531675649206e-09, -3.02224848471497e-10 } }, + { { 4, 7, 4, 7 }, { 4.12621310432840e-02, -2.99301196790539e-03 } }, + { { 4, 1, 4, 2 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 8, 1, 6, 2 }, { 3.44264964148825e-09, -9.90113228889187e-12 } }, + { { 8, 1, 8, 2 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 2, 3, 4, 2 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 6, 3, 6, 2 }, { -1.76420137108402e-09, -1.05104052143859e-10 } }, + { { 8, 3, 6, 2 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, + { { 6, 3, 8, 2 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 8, 3, 8, 2 }, { 2.71542765828882e-09, -1.76543337678833e-09 } }, + { { 8, 5, 4, 2 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 4, 5, 6, 2 }, { 1.76420137232554e-09, 1.05104055437868e-10 } }, + { { 4, 5, 8, 2 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 6, 7, 4, 2 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 2, 7, 6, 2 }, { -3.44264963006675e-09, 9.90112058323764e-12 } }, + { { 4, 7, 6, 2 }, { -5.50878617767860e-02, 1.99532026191665e-03 } }, + { { 2, 7, 8, 2 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 4, 7, 8, 2 }, { -2.71542765860322e-09, 1.76543337688875e-09 } }, + { { 6, 1, 6, 4 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, + { { 8, 1, 8, 4 }, { 8.11616423400861e-10, -1.67305274306159e-09 } }, + { { 8, 3, 6, 4 }, { -4.05111131217324e-09, 1.17669809757545e-09 } }, + { { 6, 3, 8, 4 }, { -7.35799849772961e-10, 8.96392999330838e-10 } }, + { { 8, 3, 8, 4 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 2, 5, 6, 4 }, { -7.84227887895553e-10, -8.65456802951857e-10 } }, + { { 4, 5, 8, 4 }, { 7.35799852084301e-10, -8.96392999068158e-10 } }, + { { 4, 7, 6, 4 }, { 4.05111131184309e-09, -1.17669809730382e-09 } }, + { { 2, 7, 8, 4 }, { -8.11616426817687e-10, 1.67305273280271e-09 } }, + { { 4, 7, 8, 4 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 8, 1, 2, 6 }, { 4.07154504759461e-09, -3.34683209358053e-10 } }, + { { 8, 1, 4, 6 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 4, 1, 8, 6 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 6, 3, 2, 6 }, { -1.64913548260651e-09, 1.70894051570111e-10 } }, + { { 8, 3, 2, 6 }, { 5.50878617883651e-02, -1.99531994223260e-03 } }, + { { 6, 3, 4, 6 }, { 2.77775993160253e-04, 3.77410302057860e-03 } }, + { { 8, 3, 4, 6 }, { -4.67622885738260e-09, -6.98952053415614e-10 } }, + { { 2, 3, 8, 6 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 4, 5, 2, 6 }, { 1.64913548384803e-09, -1.70894048276102e-10 } }, + { { 4, 5, 4, 6 }, { -2.77775993160253e-04, -3.77410302057860e-03 } }, + { { 8, 5, 8, 6 }, { 2.10829501478453e-03, -9.24701177434334e-03 } }, + { { 2, 7, 2, 6 }, { -4.07154503617311e-09, 3.34683197652399e-10 } }, + { { 4, 7, 2, 6 }, { -5.50878617883651e-02, 1.99531994223259e-03 } }, + { { 2, 7, 4, 6 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 4, 7, 4, 6 }, { 4.67622885713219e-09, 6.98952053111356e-10 } }, + { { 6, 7, 8, 6 }, { -2.10829501478453e-03, 9.24701177434335e-03 } }, + { { 6, 1, 2, 8 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 8, 1, 4, 8 }, { 1.49528282820932e-09, 1.95530142612850e-09 } }, + { { 8, 3, 2, 8 }, { 2.90052566099105e-09, 2.04564330047190e-09 } }, + { { 8, 3, 4, 8 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 2, 5, 2, 8 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 4, 7, 2, 8 }, { -2.90052566130477e-09, -2.04564330064451e-09 } }, + { { 2, 7, 4, 8 }, { -1.49528281786713e-09, -1.95530142297282e-09 } }, + { { 4, 7, 4, 8 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 4, 2, 4, 1 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, + { { 6, 2, 8, 1 }, { 3.44264964148825e-09, -9.90113228889187e-12 } }, + { { 8, 2, 8, 1 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, + { { 6, 4, 6, 1 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, + { { 8, 4, 8, 1 }, { 8.11616423400861e-10, -1.67305274306159e-09 } }, + { { 8, 6, 4, 1 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, + { { 2, 6, 8, 1 }, { 4.07154504759461e-09, -3.34683209358053e-10 } }, + { { 4, 6, 8, 1 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, + { { 2, 8, 6, 1 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, + { { 4, 8, 8, 1 }, { 1.49528282820932e-09, 1.95530142612850e-09 } }, + { { 4, 2, 2, 3 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, + { { 6, 2, 6, 3 }, { -1.76420137108402e-09, -1.05104052143859e-10 } }, + { { 8, 2, 6, 3 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, + { { 6, 2, 8, 3 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, + { { 8, 2, 8, 3 }, { 2.71542765828882e-09, -1.76543337678833e-09 } }, + { { 8, 4, 6, 3 }, { -7.35799849772961e-10, 8.96392999330838e-10 } }, + { { 6, 4, 8, 3 }, { -4.05111131217324e-09, 1.17669809757545e-09 } }, + { { 8, 4, 8, 3 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, + { { 8, 6, 2, 3 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, + { { 2, 6, 6, 3 }, { -1.64913548260651e-09, 1.70894051570111e-10 } }, + { { 4, 6, 6, 3 }, { 2.77775993160253e-04, 3.77410302057860e-03 } }, + { { 2, 6, 8, 3 }, { 5.50878617883651e-02, -1.99531994223260e-03 } }, + { { 4, 6, 8, 3 }, { -4.67622885738260e-09, -6.98952053415614e-10 } }, + { { 2, 8, 8, 3 }, { 2.90052566099105e-09, 2.04564330047190e-09 } }, + { { 4, 8, 8, 3 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, + { { 6, 2, 4, 5 }, { 1.76420137232554e-09, 1.05104055437868e-10 } }, + { { 8, 2, 4, 5 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, + { { 4, 2, 8, 5 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, + { { 6, 4, 2, 5 }, { -7.84227887895553e-10, -8.65456802951857e-10 } }, + { { 8, 4, 4, 5 }, { 7.35799852084301e-10, -8.96392999068158e-10 } }, + { { 2, 6, 4, 5 }, { 1.64913548384803e-09, -1.70894048276102e-10 } }, + { { 4, 6, 4, 5 }, { -2.77775993160253e-04, -3.77410302057860e-03 } }, + { { 8, 6, 8, 5 }, { 2.10829501478453e-03, -9.24701177434334e-03 } }, + { { 2, 8, 2, 5 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, + { { 6, 2, 2, 7 }, { -3.44264963006675e-09, 9.90112058323764e-12 } }, + { { 8, 2, 2, 7 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, + { { 6, 2, 4, 7 }, { -5.50878617767860e-02, 1.99532026191665e-03 } }, + { { 8, 2, 4, 7 }, { -2.71542765860322e-09, 1.76543337688875e-09 } }, + { { 4, 2, 6, 7 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, + { { 8, 4, 2, 7 }, { -8.11616426817687e-10, 1.67305273280271e-09 } }, + { { 6, 4, 4, 7 }, { 4.05111131184309e-09, -1.17669809730382e-09 } }, + { { 8, 4, 4, 7 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, + { { 2, 6, 2, 7 }, { -4.07154503617311e-09, 3.34683197652399e-10 } }, + { { 4, 6, 2, 7 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, + { { 2, 6, 4, 7 }, { -5.50878617883651e-02, 1.99531994223259e-03 } }, + { { 4, 6, 4, 7 }, { 4.67622885713219e-09, 6.98952053111356e-10 } }, + { { 8, 6, 6, 7 }, { -2.10829501478453e-03, 9.24701177434335e-03 } }, + { { 4, 8, 2, 7 }, { -1.49528281786713e-09, -1.95530142297282e-09 } }, + { { 2, 8, 4, 7 }, { -2.90052566130477e-09, -2.04564330064451e-09 } }, + { { 4, 8, 4, 7 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, + { { 2, 2, 2, 2 }, { 2.61972936056406e-01, -4.66849721298391e-17 } }, + { { 4, 2, 2, 2 }, { 1.26743997186442e-09, -9.20430828601083e-12 } }, + { { 2, 2, 4, 2 }, { 1.26743997186442e-09, -9.20430828601083e-12 } }, + { { 6, 2, 6, 2 }, { 7.34497110698912e-02, -4.26240851124491e-10 } }, + { { 8, 2, 6, 2 }, { 4.01669748482391e-09, -3.60591433307660e-09 } }, + { { 6, 2, 8, 2 }, { 4.01669748482391e-09, -3.60591433307660e-09 } }, + { { 2, 4, 2, 2 }, { 1.26743996462707e-09, 9.20431322108966e-12 } }, + { { 4, 4, 2, 2 }, { 2.61943485031872e-01, -4.89004634963355e-18 } }, + { { 2, 4, 4, 2 }, { 2.00381403996136e-02, -1.40946282423116e-18 } }, + { { 4, 4, 4, 2 }, { -1.27168924172567e-09, 9.73022873840840e-12 } }, + { { 6, 4, 6, 2 }, { -5.63030148934130e-09, 1.78997963271364e-09 } }, + { { 8, 4, 6, 2 }, { 2.22515327441311e-02, -4.31016204922364e-02 } }, + { { 6, 4, 8, 2 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 8, 4, 8, 2 }, { -4.28392086824487e-10, -3.43537540206739e-09 } }, + { { 6, 6, 2, 2 }, { 2.50873194689164e-01, 4.69906880131097e-18 } }, + { { 2, 6, 6, 2 }, { 7.34497110698912e-02, 9.76529576584216e-18 } }, + { { 4, 6, 6, 2 }, { -4.51615804141971e-09, -1.41887388113540e-09 } }, + { { 2, 6, 8, 2 }, { 3.38241175346073e-09, -2.85419828918138e-09 } }, + { { 8, 8, 2, 2 }, { 2.50828949907785e-01, -3.88899237389951e-18 } }, + { { 6, 8, 4, 2 }, { 5.62113152593797e-03, 1.41002713662608e-02 } }, + { { 2, 8, 6, 2 }, { 3.38241175231252e-09, 2.85419826357845e-09 } }, + { { 4, 8, 6, 2 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, + { { 2, 8, 8, 2 }, { 1.04255386413001e-02, 5.42101086242752e-20 } }, + { { 4, 8, 8, 2 }, { 2.15553000799339e-09, 1.31756361460964e-09 } }, + { { 2, 2, 2, 4 }, { 1.26743996462707e-09, 9.20431322108966e-12 } }, + { { 4, 2, 2, 4 }, { 2.00381403996136e-02, -1.40946282423116e-18 } }, + { { 2, 2, 4, 4 }, { 2.61943485031872e-01, -4.89004634963355e-18 } }, + { { 4, 2, 4, 4 }, { -1.27168924172567e-09, 9.73022873840840e-12 } }, + { { 6, 2, 6, 4 }, { -5.63030148934130e-09, 1.78997963271364e-09 } }, + { { 8, 2, 6, 4 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, + { { 6, 2, 8, 4 }, { 2.22515327441311e-02, -4.31016204922364e-02 } }, + { { 8, 2, 8, 4 }, { -4.28392086824487e-10, -3.43537540206739e-09 } }, + { { 4, 4, 2, 4 }, { -1.27168924980376e-09, -9.73022414045207e-12 } }, + { { 2, 4, 4, 4 }, { -1.27168924980376e-09, -9.73022414045207e-12 } }, + { { 4, 4, 4, 4 }, { 2.61914049687002e-01, 3.68803411812837e-17 } }, + { { 8, 4, 6, 4 }, { -1.11475987348867e-09, 4.36237058648892e-09 } }, + { { 6, 4, 8, 4 }, { -1.11475987348867e-09, 4.36237058648892e-09 } }, + { { 8, 4, 8, 4 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, + { { 8, 6, 2, 4 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 6, 6, 4, 4 }, { 2.50843627819692e-01, 2.68188203881229e-17 } }, + { { 2, 6, 6, 4 }, { -4.51615803043331e-09, 1.41887386867267e-09 } }, + { { 4, 6, 6, 4 }, { 1.48617254260414e-02, -2.16840434497101e-18 } }, + { { 2, 6, 8, 4 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 4, 6, 8, 4 }, { -2.00828745421621e-09, 2.74866711044360e-09 } }, + { { 8, 8, 4, 4 }, { 2.50799402750969e-01, 1.82057755524117e-17 } }, + { { 4, 8, 6, 4 }, { -2.00828744417945e-09, -2.74866710693906e-09 } }, + { { 2, 8, 8, 4 }, { 2.15552999177470e-09, -1.31756362202660e-09 } }, + { { 4, 8, 8, 4 }, { 3.20339000240785e-02, -1.73472347597681e-18 } }, + { { 6, 2, 2, 6 }, { 7.34497110698912e-02, 9.76529576584216e-18 } }, + { { 8, 2, 2, 6 }, { 3.38241175346073e-09, -2.85419828918138e-09 } }, + { { 6, 2, 4, 6 }, { -4.51615804141971e-09, -1.41887388113540e-09 } }, + { { 2, 2, 6, 6 }, { 2.50873194689164e-01, 4.69906880131097e-18 } }, + { { 6, 4, 2, 6 }, { -4.51615803043331e-09, 1.41887386867267e-09 } }, + { { 8, 4, 2, 6 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, + { { 6, 4, 4, 6 }, { 1.48617254260414e-02, -2.16840434497101e-18 } }, + { { 8, 4, 4, 6 }, { -2.00828745421621e-09, 2.74866711044360e-09 } }, + { { 4, 4, 6, 6 }, { 2.50843627819692e-01, 2.68188203881229e-17 } }, + { { 2, 4, 8, 6 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, + { { 2, 6, 2, 6 }, { 7.34497110698911e-02, 4.26240870655083e-10 } }, + { { 4, 6, 2, 6 }, { -5.63030150095342e-09, -1.78997964451953e-09 } }, + { { 2, 6, 4, 6 }, { -5.63030150095342e-09, -1.78997964451953e-09 } }, + { { 6, 6, 6, 6 }, { 2.46623945475382e-01, -9.66681842914379e-18 } }, + { { 2, 8, 2, 6 }, { 4.01669748399264e-09, 3.60591430678317e-09 } }, + { { 4, 8, 2, 6 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, + { { 2, 8, 4, 6 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 4, 8, 4, 6 }, { -1.11475986935356e-09, -4.36237059612427e-09 } }, + { { 8, 8, 6, 6 }, { 2.46582791504814e-01, 6.82292257170944e-19 } }, + { { 6, 8, 8, 6 }, { 1.31792902727351e-02, -1.24683249835833e-18 } }, + { { 6, 2, 2, 8 }, { 3.38241175231252e-09, 2.85419826357845e-09 } }, + { { 8, 2, 2, 8 }, { 1.04255386413001e-02, 5.42101086242752e-20 } }, + { { 6, 2, 4, 8 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, + { { 8, 2, 4, 8 }, { 2.15553000799339e-09, 1.31756361460964e-09 } }, + { { 4, 2, 6, 8 }, { 5.62113152593797e-03, 1.41002713662608e-02 } }, + { { 2, 2, 8, 8 }, { 2.50828949907785e-01, -3.88899237389951e-18 } }, + { { 8, 4, 2, 8 }, { 2.15552999177470e-09, -1.31756362202660e-09 } }, + { { 6, 4, 4, 8 }, { -2.00828744417945e-09, -2.74866710693906e-09 } }, + { { 8, 4, 4, 8 }, { 3.20339000240785e-02, -1.73472347597681e-18 } }, + { { 4, 4, 8, 8 }, { 2.50799402750969e-01, 1.82057755524117e-17 } }, + { { 2, 6, 2, 8 }, { 4.01669748399264e-09, 3.60591430678317e-09 } }, + { { 4, 6, 2, 8 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, + { { 2, 6, 4, 8 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, + { { 4, 6, 4, 8 }, { -1.11475986935356e-09, -4.36237059612427e-09 } }, + { { 8, 6, 6, 8 }, { 1.31792902727351e-02, -1.24683249835833e-18 } }, + { { 6, 6, 8, 8 }, { 2.46582791504814e-01, 6.82292257170944e-19 } }, + { { 4, 8, 2, 8 }, { -4.28392072459286e-10, 3.43537539337673e-09 } }, + { { 2, 8, 4, 8 }, { -4.28392072459286e-10, 3.43537539337673e-09 } }, + { { 4, 8, 4, 8 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, + { { 8, 8, 8, 8 }, { 2.46541664704192e-01, 1.10215294407731e-17 } }, + { { 1, 1, 0, 0 }, { -2.11636226073930e+00, 1.02763625347668e-18 } }, + { { 5, 1, 0, 0 }, { 1.19046590368770e-09, -5.57499617699363e-12 } }, + { { 3, 3, 0, 0 }, { -2.11591498795759e+00, 8.09942036238525e-17 } }, + { { 5, 5, 0, 0 }, { -1.68636099808535e+00, 7.71371067496320e-18 } }, + { { 7, 7, 0, 0 }, { -1.68576161450246e+00, 3.76062776246208e-18 } }, + { { 2, 2, 0, 0 }, { -2.11636226073930e+00, 5.03521382473279e-19 } }, + { { 6, 2, 0, 0 }, { 1.19046603507266e-09, 5.57499896179912e-12 } }, + { { 4, 4, 0, 0 }, { -2.11591498795759e+00, 1.35457336871340e-16 } }, + { { 6, 6, 0, 0 }, { -1.68636099808535e+00, -8.60733043431649e-18 } }, + { { 8, 8, 0, 0 }, { -1.68576161450246e+00, -9.10040816524792e-17 } }, + { { 0, 0, 0, 0 }, { -1.02932237633033e+02, 0.00000000000000e+00 } } }; + // == PARAMETER CONTAINER == + parametersComplex.set("integrals_binary", maquis::serialize(integralsComplex)); + parametersComplex.set("site_types", "1,1,1,1,1,1,1,1"); + parametersComplex.set("L", 8); + parametersComplex.set("irrep", 1); + parametersComplex.set("nsweeps", 10); + parametersComplex.set("max_bond_dimension", 512); + parametersComplex.set("nelec", 3); + maquis::prepare_relativistic(parametersComplex); + parametersComplex.set("MEASURE[1rdm]","1"); + parametersComplex.set("MEASURE[2rdm]","1"); + } + // Class members + ComplexIntegralMapType integralsComplex; + DmrgParameters parametersComplex; +}; + +#endif \ No newline at end of file diff --git a/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops.cpp b/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_TwoU1.cpp similarity index 99% rename from dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops.cpp rename to dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_TwoU1.cpp index ec59eea33..98442c282 100644 --- a/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops.cpp +++ b/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_TwoU1.cpp @@ -32,13 +32,11 @@ #include #include "utils/fpcomparison.h" #include - #include "utils/io.hpp" // has to be first include because of impi #include #include "dmrg/mp_tensors/mps.h" #include "dmrg/mp_tensors/mps_rotate.h" #include "dmrg/sim/matrix_types.h" - #include "test_mps.h" typedef boost::mpl::list< diff --git a/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_electronic.cpp b/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_electronic.cpp new file mode 100644 index 000000000..2b9f17f77 --- /dev/null +++ b/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_electronic.cpp @@ -0,0 +1,119 @@ +/***************************************************************************** +* +* ALPS MPS DMRG Project +* +* Copyright (C) 2021 Institute for Theoretical Physics, ETH Zurich +* 2021- Alberto Baiardi +* +* This software is part of the ALPS Applications, published under the ALPS +* Application License; you can use, redistribute it and/or modify it under +* the terms of the license, either version 1 or (at your option) any later +* version. +* +* You should have received a copy of the ALPS Application License along with +* the ALPS Applications; see the file LICENSE.txt. If not, the license is also +* available from http://alps.comp-phys.org/. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +// This files contains the tests that check the functionality of the +// methods stored in the [mps_mpo_ops] files and that are generic, +// meaning that they can be tested for both the TwoU1 and the SU2U1 +// group. + +#define BOOST_TEST_MAIN + +#include +#include "utils/fpcomparison.h" +#include +#include "utils/io.hpp" // has to be first include because of impi +#include +#include "dmrg/mp_tensors/mps.h" +#include "dmrg/mp_tensors/mps_rotate.h" +#include "dmrg/sim/matrix_types.h" +#include "Fixtures/BenzeneFixture.h" +#include "test_mps.h" + +typedef boost::mpl::list< +#ifdef HAVE_TwoU1PG +TwoU1PG +#endif +#ifdef HAVE_SU2U1PG +, SU2U1PG +#endif +> symmetries; + +/** + * @brief Checks that the MPO-MPS contraction fulfill the Hermitianity of the Hamiltonian + * Note that this test uses the "standard" implementation of the expval function, which uses the left boundary. + */ +BOOST_FIXTURE_TEST_CASE_TEMPLATE( Test_MPS_MPO_Hermitian_Left_Electronic, S, symmetries, BenzeneFixture ) +{ + // Generates the HF MPS + auto lattice = Lattice(parametersBenzene); + auto modelHF = Model(lattice, parametersBenzene); + auto mpsHF = MPS(lattice.size(), *(modelHF.initializer(lattice, parametersBenzene))); + // Generates the const guess. Note that the bond dimension will be != than that of the HF + // guess, so we check that the contraction routines work also for MPS with different bond dimension. + parametersBenzene.set("init_state", "const"); + auto modelConst = Model(lattice, parametersBenzene); + auto mpsConst = MPS(lattice.size(), *(modelConst.initializer(lattice, parametersBenzene))); + // Generates the default guess + parametersBenzene.set("init_state", "default"); + auto modelDefault = Model(lattice, parametersBenzene); + auto mpsDefault = MPS(lattice.size(), *(modelDefault.initializer(lattice, parametersBenzene))); + // Calculates the MPO (any model would work here) + auto mpo = make_mpo(lattice, modelConst); + // Check 1 + double expVal1 = expval(mpsDefault, mpsConst, mpo); + double expVal2 = expval(mpsConst, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 2 + expVal1 = expval(mpsHF, mpsConst, mpo); + expVal2 = expval(mpsConst, mpsHF, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 3 + expVal1 = expval(mpsDefault, mpsHF, mpo); + expVal2 = expval(mpsHF, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); +} + +/** @brief Same as above, but with the right boundaries */ +BOOST_FIXTURE_TEST_CASE_TEMPLATE( Test_MPS_MPO_Hermitian_Right_Electronic, S, symmetries, BenzeneFixture ) +{ + // Generates the HF MPS + auto lattice = Lattice(parametersBenzene); + auto modelHF = Model(lattice, parametersBenzene); + auto mpsHF = MPS(lattice.size(), *(modelHF.initializer(lattice, parametersBenzene))); + // Generates the const guess. Note that the bond dimension will be != than that of the HF + // guess, so we check that the contraction routines work also for MPS with different bond dimension. + parametersBenzene.set("init_state", "const"); + auto modelConst = Model(lattice, parametersBenzene); + auto mpsConst = MPS(lattice.size(), *(modelConst.initializer(lattice, parametersBenzene))); + // Generates the default guess + parametersBenzene.set("init_state", "default"); + auto modelDefault = Model(lattice, parametersBenzene); + auto mpsDefault = MPS(lattice.size(), *(modelDefault.initializer(lattice, parametersBenzene))); + // Calculates the MPO (any model would work here) + auto mpo = make_mpo(lattice, modelConst); + // Check 1 + double expVal1 = expvalFromRight(mpsDefault, mpsConst, mpo); + double expVal2 = expvalFromRight(mpsConst, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 2 + expVal1 = expvalFromRight(mpsHF, mpsConst, mpo); + expVal2 = expvalFromRight(mpsConst, mpsHF, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 3 + expVal1 = expvalFromRight(mpsDefault, mpsHF, mpo); + expVal2 = expvalFromRight(mpsHF, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); +} \ No newline at end of file diff --git a/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_prebo.cpp b/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_prebo.cpp new file mode 100644 index 000000000..3e8dfab61 --- /dev/null +++ b/dmrg/tests/test_mps_mpo_ops/test_mps_mpo_ops_prebo.cpp @@ -0,0 +1,115 @@ +/***************************************************************************** +* +* ALPS MPS DMRG Project +* +* Copyright (C) 2021 Institute for Theoretical Physics, ETH Zurich +* 2021- Alberto Baiardi +* +* This software is part of the ALPS Applications, published under the ALPS +* Application License; you can use, redistribute it and/or modify it under +* the terms of the license, either version 1 or (at your option) any later +* version. +* +* You should have received a copy of the ALPS Application License along with +* the ALPS Applications; see the file LICENSE.txt. If not, the license is also +* available from http://alps.comp-phys.org/. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +// This files contains the tests that check the functionality of the +// methods stored in the [mps_mpo_ops] files and that are generic, +// meaning that they can be tested for both the TwoU1 and the SU2U1 +// group. + +#define BOOST_TEST_MAIN + +#include +#include "utils/fpcomparison.h" +#include +#include "utils/io.hpp" // has to be first include because of impi +#include +#include "dmrg/mp_tensors/mps.h" +#include "dmrg/mp_tensors/mps_rotate.h" +#include "dmrg/sim/matrix_types.h" +#include "Fixtures/PreBOTimeEvolversFixture.h" +#include "test_mps.h" + +typedef boost::mpl::list< +NU1_template<4> +> symmetries; + +/** + * @brief Checks that the MPO-MPS contraction fulfill the Hermitianity of the Hamiltonian + * Note that this test uses the "standard" implementation of the expval function, which uses the left boundary. + */ +BOOST_FIXTURE_TEST_CASE_TEMPLATE( Test_MPS_MPO_Hermitian_Left_Electronic, S, symmetries, PreBOTestTimeEvolverFixture ) +{ + // Generates the HF MPS + auto lattice = Lattice(parametersPreBOReal); + auto modelHF = Model(lattice, parametersPreBOReal); + auto mpsHF = MPS(lattice.size(), *(modelHF.initializer(lattice, parametersPreBOReal))); + // Generates the const guess. Note that the bond dimension will be != than that of the HF + // guess, so we check that the contraction routines work also for MPS with different bond dimension. + parametersPreBOReal.set("init_state", "const"); + auto modelConst = Model(lattice, parametersPreBOReal); + auto mpsConst = MPS(lattice.size(), *(modelConst.initializer(lattice, parametersPreBOReal))); + // Generates the default guess + parametersPreBOReal.set("init_state", "default"); + auto modelDefault = Model(lattice, parametersPreBOReal); + auto mpsDefault = MPS(lattice.size(), *(modelDefault.initializer(lattice, parametersPreBOReal))); + // Calculates the MPO (any model would work here) + auto mpo = make_mpo(lattice, modelConst); + // Check 1 + double expVal1 = expval(mpsDefault, mpsConst, mpo); + double expVal2 = expval(mpsConst, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 2 + expVal1 = expval(mpsHF, mpsConst, mpo); + expVal2 = expval(mpsConst, mpsHF, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 3 + expVal1 = expval(mpsDefault, mpsHF, mpo); + expVal2 = expval(mpsHF, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); +} + +/** @brief Same as above, but with the right boundaries */ +BOOST_FIXTURE_TEST_CASE_TEMPLATE( Test_MPS_MPO_Hermitian_Right_Electronic, S, symmetries, PreBOTestTimeEvolverFixture ) +{ + // Generates the HF MPS + auto lattice = Lattice(parametersPreBOReal); + auto modelHF = Model(lattice, parametersPreBOReal); + auto mpsHF = MPS(lattice.size(), *(modelHF.initializer(lattice, parametersPreBOReal))); + // Generates the const guess. Note that the bond dimension will be != than that of the HF + // guess, so we check that the contraction routines work also for MPS with different bond dimension. + parametersPreBOReal.set("init_state", "const"); + auto modelConst = Model(lattice, parametersPreBOReal); + auto mpsConst = MPS(lattice.size(), *(modelConst.initializer(lattice, parametersPreBOReal))); + // Generates the default guess + parametersPreBOReal.set("init_state", "default"); + auto modelDefault = Model(lattice, parametersPreBOReal); + auto mpsDefault = MPS(lattice.size(), *(modelDefault.initializer(lattice, parametersPreBOReal))); + // Calculates the MPO (any model would work here) + auto mpo = make_mpo(lattice, modelConst); + // Check 1 + double expVal1 = expvalFromRight(mpsDefault, mpsConst, mpo); + double expVal2 = expvalFromRight(mpsConst, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 2 + expVal1 = expvalFromRight(mpsHF, mpsConst, mpo); + expVal2 = expvalFromRight(mpsConst, mpsHF, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); + // Check 3 + expVal1 = expvalFromRight(mpsDefault, mpsHF, mpo); + expVal2 = expvalFromRight(mpsHF, mpsDefault, mpo); + BOOST_CHECK_CLOSE(expVal1, expVal2, 1.E-10); +} + diff --git a/dmrg/tests/test_mps_mpo_ops/test_mps_overlap_electronic.cpp b/dmrg/tests/test_mps_mpo_ops/test_mps_overlap_electronic.cpp new file mode 100644 index 000000000..22167ebef --- /dev/null +++ b/dmrg/tests/test_mps_mpo_ops/test_mps_overlap_electronic.cpp @@ -0,0 +1,98 @@ +/***************************************************************************** +* +* ALPS MPS DMRG Project +* +* Copyright (C) 2021 Institute for Theoretical Physics, ETH Zurich +* 2021- Alberto Baiardi +* +* This software is part of the ALPS Applications, published under the ALPS +* Application License; you can use, redistribute it and/or modify it under +* the terms of the license, either version 1 or (at your option) any later +* version. +* +* You should have received a copy of the ALPS Application License along with +* the ALPS Applications; see the file LICENSE.txt. If not, the license is also +* available from http://alps.comp-phys.org/. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#define BOOST_TEST_MODULE MPSOverlapElectronic + +#include +#include +#include "dmrg/models/lattice.h" +#include "dmrg/models/model.h" +#include "dmrg/mp_tensors/mps.h" +#include "dmrg/sim/matrix_types.h" +#include "Fixtures/BenzeneFixture.h" +#include "Fixtures/RelativisticFixture.h" +#include "dmrg/models/generate_mpo.hpp" +#include "dmrg/mp_tensors/mps_mpo_ops.h" + +typedef boost::mpl::list< +#ifdef HAVE_TwoU1PG +TwoU1PG +#endif +#ifdef HAVE_SU2U1PG +, SU2U1PG +#endif +> symmetries; + +/** @brief Checks that overlap and norm give coherent results for the electronic case */ +BOOST_FIXTURE_TEST_CASE_TEMPLATE( Test_MPS_Overlap_Electronic, S, symmetries, BenzeneFixture ) +{ + // Modifies the last parameters + auto lattice = Lattice(parametersBenzene); + auto model = Model(lattice, parametersBenzene); + auto mpsHF = MPS(lattice.size(), *(model.initializer(lattice, parametersBenzene))); + double normHF = norm(mpsHF); + double overlapHF = overlap(mpsHF, mpsHF); + BOOST_CHECK_CLOSE(normHF, overlapHF, 1.E-10); +} + +/** @brief Checks Hermitianity of the overlap calculation for the real-valued electronic case */ +BOOST_FIXTURE_TEST_CASE_TEMPLATE( Test_MPS_Overlap_Hermitian_Electronic, S, symmetries, BenzeneFixture ) +{ + // Global variables + auto lattice = Lattice(parametersBenzene); + auto model = Model(lattice, parametersBenzene); + // Modifies the init parameters to create two different MPSs + parametersBenzene.set("init_state", "const"); + auto mpsConst = MPS(lattice.size(), *(model.initializer(lattice, parametersBenzene))); + parametersBenzene.set("init_state", "default"); + auto mpsDefault = MPS(lattice.size(), *(model.initializer(lattice, parametersBenzene))); + // Calculates the overlap + double overlapOriginal = overlap(mpsConst, mpsDefault); + double overlapHerm = overlap(mpsDefault, mpsConst); + BOOST_CHECK_CLOSE(overlapOriginal, overlapHerm, 1.E-10); +} + +#ifdef HAVE_U1DG + +/** @brief Checks Hermitianity of the overlap calculation for the relativistic (complex-valued) electronic case */ +BOOST_FIXTURE_TEST_CASE( Test_MPS_Overlap_Hermitian_Electronic_Complex, RelativisticFixture ) +{ + // Global variables + auto lattice = Lattice(parametersComplex); + auto model = Model(lattice, parametersComplex); + // Modifies the init parameters to create two different MPSs + parametersComplex.set("init_state", "const"); + auto mpsConst = MPS(lattice.size(), *(model.initializer(lattice, parametersComplex))); + parametersComplex.set("init_state", "default"); + auto mpsDefault = MPS(lattice.size(), *(model.initializer(lattice, parametersComplex))); + // Calculates the overlap + std::complex overlapOriginal = overlap(mpsConst, mpsDefault); + std::complex overlapHerm = overlap(mpsDefault, mpsConst); + BOOST_CHECK_CLOSE(std::real(overlapOriginal), std::real(overlapHerm), 1.E-10); + BOOST_CHECK_CLOSE(std::imag(overlapOriginal), -std::imag(overlapHerm), 1.E-10); +} + +#endif \ No newline at end of file diff --git a/dmrg/tests/test_rel.cpp b/dmrg/tests/test_rel.cpp index 9e2113153..65ba986aa 100644 --- a/dmrg/tests/test_rel.cpp +++ b/dmrg/tests/test_rel.cpp @@ -5,6 +5,7 @@ * Copyright (C) 2014 Institute for Theoretical Physics, ETH Zurich * 2011-2013 by Michele Dolfi * 2019 by Leon Freitag + * 2021 by Alberto Baiardi * * This software is part of the ALPS Applications, published under the ALPS * Application License; you can use, redistribute it and/or modify it under @@ -31,1012 +32,23 @@ #include "utils/fpcomparison.h" #include "utils/io.hpp" // has to be first include because of impi #include +#include "Fixtures/RelativisticFixture.h" -#include "maquis_dmrg.h" -// Relativistic test: N2+, (3e,8o) 3-21G basis: stknecht: please update description -BOOST_AUTO_TEST_CASE( Test_Relativistic ) +/** @brief N2 energy with 4c-DMRG */ +BOOST_FIXTURE_TEST_CASE( Test_Relativistic, RelativisticFixture ) { // only enable the test if we compile the support for the U1DG symmetry - #ifdef HAVE_U1DG - DmrgParameters p; - - typedef std::complex Complex; - - const maquis::integral_map integrals { - { { 1, 1, 1, 1 }, { 2.61972936056406e-01, -5.93576335462699e-17 } }, - { { 3, 1, 1, 1 }, { 1.26743997238509e-09, 9.20431282901706e-12 } }, - { { 1, 1, 3, 1 }, { 1.26743997238509e-09, 9.20431282901706e-12 } }, - { { 5, 1, 5, 1 }, { 7.34497110698912e-02, 4.26240897602650e-10 } }, - { { 7, 1, 5, 1 }, { 4.01669748480819e-09, 3.60591432811921e-09 } }, - { { 5, 1, 7, 1 }, { 4.01669748480819e-09, 3.60591432811921e-09 } }, - { { 1, 3, 1, 1 }, { 1.26743996410745e-09, -9.20429997217042e-12 } }, - { { 3, 3, 1, 1 }, { 2.61943485031872e-01, -2.00991307043607e-17 } }, - { { 1, 3, 3, 1 }, { 2.00381403996136e-02, -1.08420217248550e-18 } }, - { { 3, 3, 3, 1 }, { -1.27168924225649e-09, -9.73022387800160e-12 } }, - { { 5, 3, 5, 1 }, { -5.63030148897478e-09, -1.78997963409621e-09 } }, - { { 7, 3, 5, 1 }, { 2.22515327441311e-02, 4.31016204922364e-02 } }, - { { 5, 3, 7, 1 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 7, 3, 7, 1 }, { -4.28392084589810e-10, 3.43537540037891e-09 } }, - { { 5, 5, 1, 1 }, { 2.50873194689164e-01, 1.65168461057214e-17 } }, - { { 1, 5, 5, 1 }, { 7.34497110698912e-02, 1.89915634214172e-17 } }, - { { 3, 5, 5, 1 }, { -4.51615804178781e-09, 1.41887387086788e-09 } }, - { { 1, 5, 7, 1 }, { 3.38241175380762e-09, 2.85419828473184e-09 } }, - { { 7, 7, 1, 1 }, { 2.50828949907785e-01, -2.00659972392514e-17 } }, - { { 5, 7, 3, 1 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 1, 7, 5, 1 }, { 3.38241175232689e-09, -2.85419826760833e-09 } }, - { { 3, 7, 5, 1 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 1, 7, 7, 1 }, { 1.04255386413001e-02, 4.87890977618477e-19 } }, - { { 3, 7, 7, 1 }, { 2.15553000473605e-09, -1.31756361634581e-09 } }, - { { 1, 1, 1, 3 }, { 1.26743996410745e-09, -9.20429997217042e-12 } }, - { { 3, 1, 1, 3 }, { 2.00381403996136e-02, -1.08420217248550e-18 } }, - { { 1, 1, 3, 3 }, { 2.61943485031872e-01, -2.00991307043607e-17 } }, - { { 3, 1, 3, 3 }, { -1.27168924225649e-09, -9.73022387800160e-12 } }, - { { 5, 1, 5, 3 }, { -5.63030148897478e-09, -1.78997963409621e-09 } }, - { { 7, 1, 5, 3 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 5, 1, 7, 3 }, { 2.22515327441311e-02, 4.31016204922364e-02 } }, - { { 7, 1, 7, 3 }, { -4.28392084589810e-10, 3.43537540037891e-09 } }, - { { 3, 3, 1, 3 }, { -1.27168924927192e-09, 9.73023774231880e-12 } }, - { { 1, 3, 3, 3 }, { -1.27168924927192e-09, 9.73023774231880e-12 } }, - { { 3, 3, 3, 3 }, { 2.61914049687002e-01, 1.91403429621010e-17 } }, - { { 7, 3, 5, 3 }, { -1.11475987224334e-09, -4.36237058644354e-09 } }, - { { 5, 3, 7, 3 }, { -1.11475987224334e-09, -4.36237058644354e-09 } }, - { { 7, 3, 7, 3 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, - { { 7, 5, 1, 3 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, - { { 5, 5, 3, 3 }, { 2.50843627819692e-01, 3.76855130433924e-17 } }, - { { 1, 5, 5, 3 }, { -4.51615803079038e-09, -1.41887387023288e-09 } }, - { { 3, 5, 5, 3 }, { 1.48617254260414e-02, -4.33680868994202e-19 } }, - { { 1, 5, 7, 3 }, { 2.22515329942571e-02, 4.31016203631070e-02 } }, - { { 3, 5, 7, 3 }, { -2.00828744878274e-09, -2.74866711310747e-09 } }, - { { 7, 7, 3, 3 }, { 2.50799402750969e-01, 1.10201871793512e-18 } }, - { { 3, 7, 5, 3 }, { -2.00828744429202e-09, 2.74866710701661e-09 } }, - { { 1, 7, 7, 3 }, { 2.15552999444319e-09, 1.31756362061684e-09 } }, - { { 3, 7, 7, 3 }, { 3.20339000240785e-02, -3.46944695195361e-18 } }, - { { 5, 1, 1, 5 }, { 7.34497110698912e-02, 1.89915634214172e-17 } }, - { { 7, 1, 1, 5 }, { 3.38241175380762e-09, 2.85419828473184e-09 } }, - { { 5, 1, 3, 5 }, { -4.51615804178781e-09, 1.41887387086788e-09 } }, - { { 1, 1, 5, 5 }, { 2.50873194689164e-01, 1.65168461057214e-17 } }, - { { 5, 3, 1, 5 }, { -4.51615803079038e-09, -1.41887387023288e-09 } }, - { { 7, 3, 1, 5 }, { 2.22515329942571e-02, 4.31016203631070e-02 } }, - { { 5, 3, 3, 5 }, { 1.48617254260414e-02, -4.33680868994202e-19 } }, - { { 7, 3, 3, 5 }, { -2.00828744878274e-09, -2.74866711310747e-09 } }, - { { 3, 3, 5, 5 }, { 2.50843627819692e-01, 3.76855130433924e-17 } }, - { { 1, 3, 7, 5 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, - { { 1, 5, 1, 5 }, { 7.34497110698911e-02, -4.26240859619522e-10 } }, - { { 3, 5, 1, 5 }, { -5.63030150059789e-09, 1.78997963407439e-09 } }, - { { 1, 5, 3, 5 }, { -5.63030150059789e-09, 1.78997963407439e-09 } }, - { { 5, 5, 5, 5 }, { 2.46623945475382e-01, 7.18015643244974e-19 } }, - { { 1, 7, 1, 5 }, { 4.01669748364437e-09, -3.60591431030523e-09 } }, - { { 3, 7, 1, 5 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, - { { 1, 7, 3, 5 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 3, 7, 3, 5 }, { -1.11475987592073e-09, 4.36237059349358e-09 } }, - { { 7, 7, 5, 5 }, { 2.46582791504814e-01, 9.33242001386412e-19 } }, - { { 5, 7, 7, 5 }, { 1.31792902727351e-02, 7.04731412115578e-19 } }, - { { 5, 1, 1, 7 }, { 3.38241175232689e-09, -2.85419826760833e-09 } }, - { { 7, 1, 1, 7 }, { 1.04255386413001e-02, 4.87890977618477e-19 } }, - { { 5, 1, 3, 7 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 7, 1, 3, 7 }, { 2.15553000473605e-09, -1.31756361634581e-09 } }, - { { 3, 1, 5, 7 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 1, 1, 7, 7 }, { 2.50828949907785e-01, -2.00659972392514e-17 } }, - { { 7, 3, 1, 7 }, { 2.15552999444319e-09, 1.31756362061684e-09 } }, - { { 5, 3, 3, 7 }, { -2.00828744429202e-09, 2.74866710701661e-09 } }, - { { 7, 3, 3, 7 }, { 3.20339000240785e-02, -3.46944695195361e-18 } }, - { { 3, 3, 7, 7 }, { 2.50799402750969e-01, 1.10201871793512e-18 } }, - { { 1, 5, 1, 7 }, { 4.01669748364437e-09, -3.60591431030523e-09 } }, - { { 3, 5, 1, 7 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 1, 5, 3, 7 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, - { { 3, 5, 3, 7 }, { -1.11475987592073e-09, 4.36237059349358e-09 } }, - { { 7, 5, 5, 7 }, { 1.31792902727351e-02, 7.04731412115578e-19 } }, - { { 5, 5, 7, 7 }, { 2.46582791504814e-01, 9.33242001386412e-19 } }, - { { 3, 7, 1, 7 }, { -4.28392074105941e-10, -3.43537539483338e-09 } }, - { { 1, 7, 3, 7 }, { -4.28392074105941e-10, -3.43537539483338e-09 } }, - { { 3, 7, 3, 7 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, - { { 7, 7, 7, 7 }, { 2.46541664704192e-01, 1.14435014084414e-18 } }, - { { 3, 1, 3, 2 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 5, 1, 7, 2 }, { -3.44264963011916e-09, -9.90112075686836e-12 } }, - { { 7, 1, 7, 2 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 5, 3, 5, 2 }, { -7.84227887895554e-10, 8.65456802951857e-10 } }, - { { 7, 3, 7, 2 }, { -8.11616426840793e-10, -1.67305273292072e-09 } }, - { { 7, 5, 3, 2 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 1, 5, 7, 2 }, { -4.07154503624496e-09, -3.34683197320015e-10 } }, - { { 3, 5, 7, 2 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 1, 7, 5, 2 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 3, 7, 7, 2 }, { -1.49528281775848e-09, 1.95530142301122e-09 } }, - { { 3, 1, 1, 4 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 5, 1, 5, 4 }, { 1.76420137225424e-09, -1.05104055409810e-10 } }, - { { 7, 1, 5, 4 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 5, 1, 7, 4 }, { -5.50878617767860e-02, -1.99532026191666e-03 } }, - { { 7, 1, 7, 4 }, { -2.71542765827455e-09, -1.76543336029064e-09 } }, - { { 7, 3, 5, 4 }, { 7.35799852035404e-10, 8.96392999081955e-10 } }, - { { 5, 3, 7, 4 }, { 4.05111132035920e-09, 1.17669809883779e-09 } }, - { { 7, 3, 7, 4 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 7, 5, 1, 4 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 1, 5, 5, 4 }, { 1.64913548399047e-09, 1.70894048294891e-10 } }, - { { 3, 5, 5, 4 }, { -2.77775993160252e-04, 3.77410302057860e-03 } }, - { { 1, 5, 7, 4 }, { -5.50878617883651e-02, -1.99531994223258e-03 } }, - { { 3, 5, 7, 4 }, { 4.67622884828570e-09, -6.98952045491450e-10 } }, - { { 1, 7, 7, 4 }, { -2.90052566280734e-09, 2.04564331648436e-09 } }, - { { 3, 7, 7, 4 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 5, 1, 3, 6 }, { -1.76420137101272e-09, 1.05104052115801e-10 } }, - { { 7, 1, 3, 6 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 3, 1, 7, 6 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 5, 3, 1, 6 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, - { { 7, 3, 3, 6 }, { -7.35799849724064e-10, -8.96392999344636e-10 } }, - { { 1, 5, 3, 6 }, { -1.64913548274895e-09, -1.70894051588900e-10 } }, - { { 3, 5, 3, 6 }, { 2.77775993160252e-04, -3.77410302057860e-03 } }, - { { 7, 5, 7, 6 }, { -2.10829501478453e-03, -9.24701177434334e-03 } }, - { { 1, 7, 1, 6 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 5, 1, 1, 8 }, { 3.44264964154066e-09, 9.90113246252263e-12 } }, - { { 7, 1, 1, 8 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 5, 1, 3, 8 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, - { { 7, 1, 3, 8 }, { 2.71542765796015e-09, 1.76543336019022e-09 } }, - { { 3, 1, 5, 8 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 7, 3, 1, 8 }, { 8.11616423423967e-10, 1.67305274317960e-09 } }, - { { 5, 3, 3, 8 }, { -4.05111132068935e-09, -1.17669809910942e-09 } }, - { { 7, 3, 3, 8 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 1, 5, 1, 8 }, { 4.07154504766646e-09, 3.34683209025669e-10 } }, - { { 3, 5, 1, 8 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 1, 5, 3, 8 }, { 5.50878617883651e-02, 1.99531994223259e-03 } }, - { { 3, 5, 3, 8 }, { -4.67622884853612e-09, 6.98952045795709e-10 } }, - { { 7, 5, 5, 8 }, { 2.10829501478453e-03, 9.24701177434335e-03 } }, - { { 3, 7, 1, 8 }, { 1.49528282810068e-09, -1.95530142616690e-09 } }, - { { 1, 7, 3, 8 }, { 2.90052566249363e-09, -2.04564331631174e-09 } }, - { { 3, 7, 3, 8 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 3, 2, 3, 1 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 7, 2, 5, 1 }, { -3.44264963011916e-09, -9.90112075686836e-12 } }, - { { 7, 2, 7, 1 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 1, 4, 3, 1 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 5, 4, 5, 1 }, { 1.76420137225424e-09, -1.05104055409810e-10 } }, - { { 7, 4, 5, 1 }, { -5.50878617767860e-02, -1.99532026191666e-03 } }, - { { 5, 4, 7, 1 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 7, 4, 7, 1 }, { -2.71542765827455e-09, -1.76543336029064e-09 } }, - { { 7, 6, 3, 1 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 3, 6, 5, 1 }, { -1.76420137101272e-09, 1.05104052115801e-10 } }, - { { 3, 6, 7, 1 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 5, 8, 3, 1 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 1, 8, 5, 1 }, { 3.44264964154066e-09, 9.90113246252263e-12 } }, - { { 3, 8, 5, 1 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, - { { 1, 8, 7, 1 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 3, 8, 7, 1 }, { 2.71542765796015e-09, 1.76543336019022e-09 } }, - { { 5, 2, 5, 3 }, { -7.84227887895554e-10, 8.65456802951857e-10 } }, - { { 7, 2, 7, 3 }, { -8.11616426840793e-10, -1.67305273292072e-09 } }, - { { 7, 4, 5, 3 }, { 4.05111132035920e-09, 1.17669809883779e-09 } }, - { { 5, 4, 7, 3 }, { 7.35799852035404e-10, 8.96392999081955e-10 } }, - { { 7, 4, 7, 3 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 1, 6, 5, 3 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, - { { 3, 6, 7, 3 }, { -7.35799849724064e-10, -8.96392999344636e-10 } }, - { { 3, 8, 5, 3 }, { -4.05111132068935e-09, -1.17669809910942e-09 } }, - { { 1, 8, 7, 3 }, { 8.11616423423967e-10, 1.67305274317960e-09 } }, - { { 3, 8, 7, 3 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 7, 2, 1, 5 }, { -4.07154503624496e-09, -3.34683197320015e-10 } }, - { { 7, 2, 3, 5 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 3, 2, 7, 5 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 5, 4, 1, 5 }, { 1.64913548399047e-09, 1.70894048294891e-10 } }, - { { 7, 4, 1, 5 }, { -5.50878617883651e-02, -1.99531994223258e-03 } }, - { { 5, 4, 3, 5 }, { -2.77775993160252e-04, 3.77410302057860e-03 } }, - { { 7, 4, 3, 5 }, { 4.67622884828570e-09, -6.98952045491450e-10 } }, - { { 1, 4, 7, 5 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 3, 6, 1, 5 }, { -1.64913548274895e-09, -1.70894051588900e-10 } }, - { { 3, 6, 3, 5 }, { 2.77775993160252e-04, -3.77410302057860e-03 } }, - { { 7, 6, 7, 5 }, { -2.10829501478453e-03, -9.24701177434334e-03 } }, - { { 1, 8, 1, 5 }, { 4.07154504766646e-09, 3.34683209025669e-10 } }, - { { 3, 8, 1, 5 }, { 5.50878617883651e-02, 1.99531994223259e-03 } }, - { { 1, 8, 3, 5 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 3, 8, 3, 5 }, { -4.67622884853612e-09, 6.98952045795709e-10 } }, - { { 5, 8, 7, 5 }, { 2.10829501478453e-03, 9.24701177434335e-03 } }, - { { 5, 2, 1, 7 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 7, 2, 3, 7 }, { -1.49528281775848e-09, 1.95530142301122e-09 } }, - { { 7, 4, 1, 7 }, { -2.90052566280734e-09, 2.04564331648436e-09 } }, - { { 7, 4, 3, 7 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 1, 6, 1, 7 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 3, 8, 1, 7 }, { 2.90052566249363e-09, -2.04564331631174e-09 } }, - { { 1, 8, 3, 7 }, { 1.49528282810068e-09, -1.95530142616690e-09 } }, - { { 3, 8, 3, 7 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 7, 2, 5, 2 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 5, 2, 7, 2 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 5, 4, 5, 2 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 7, 4, 7, 2 }, { 2.62531675649206e-09, 3.02224848471497e-10 } }, - { { 3, 6, 5, 2 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 1, 6, 7, 2 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 1, 8, 5, 2 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 3, 8, 7, 2 }, { -2.62531675639996e-09, -3.02224848795605e-10 } }, - { { 5, 2, 5, 4 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 7, 2, 7, 4 }, { 2.62531675649206e-09, 3.02224848471497e-10 } }, - { { 7, 4, 5, 4 }, { -1.24277413513931e-09, 5.61668777968849e-12 } }, - { { 5, 4, 7, 4 }, { -1.24277413513931e-09, 5.61668777968849e-12 } }, - { { 7, 4, 7, 4 }, { 4.12621310432840e-02, 2.99301196790539e-03 } }, - { { 1, 6, 5, 4 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 3, 6, 7, 4 }, { 1.24277413595630e-09, -5.61668436628098e-12 } }, - { { 3, 8, 5, 4 }, { 1.24277413499966e-09, -5.61668780729011e-12 } }, - { { 1, 8, 7, 4 }, { -2.62531674833921e-09, -3.02224836559841e-10 } }, - { { 3, 8, 7, 4 }, { -4.12621310432840e-02, -2.99301196790539e-03 } }, - { { 7, 2, 1, 6 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 5, 2, 3, 6 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 5, 4, 1, 6 }, { -3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 7, 4, 3, 6 }, { 1.24277413595630e-09, -5.61668436628098e-12 } }, - { { 3, 6, 1, 6 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 1, 6, 3, 6 }, { 3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 1, 8, 1, 6 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 3, 8, 3, 6 }, { -1.24277413581665e-09, 5.61668439388257e-12 } }, - { { 5, 2, 1, 8 }, { 1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 7, 2, 3, 8 }, { -2.62531675639996e-09, -3.02224848795605e-10 } }, - { { 7, 4, 1, 8 }, { -2.62531674833921e-09, -3.02224836559841e-10 } }, - { { 5, 4, 3, 8 }, { 1.24277413499966e-09, -5.61668780729011e-12 } }, - { { 7, 4, 3, 8 }, { -4.12621310432840e-02, -2.99301196790539e-03 } }, - { { 1, 6, 1, 8 }, { -1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 3, 6, 3, 8 }, { -1.24277413581665e-09, 5.61668439388257e-12 } }, - { { 3, 8, 1, 8 }, { 2.62531674824712e-09, 3.02224836883949e-10 } }, - { { 1, 8, 3, 8 }, { 2.62531674824712e-09, 3.02224836883949e-10 } }, - { { 3, 8, 3, 8 }, { 4.12621310432840e-02, 2.99301196790540e-03 } }, - { { 7, 1, 6, 1 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 5, 1, 8, 1 }, { 4.07154504766646e-09, -3.34683209025669e-10 } }, - { { 1, 3, 4, 1 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 5, 3, 8, 1 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 7, 3, 8, 1 }, { 1.49528282810068e-09, 1.95530142616690e-09 } }, - { { 3, 5, 6, 1 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, - { { 1, 5, 8, 1 }, { 3.44264964154066e-09, -9.90113246252263e-12 } }, - { { 5, 7, 4, 1 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 1, 7, 8, 1 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 3, 7, 8, 1 }, { 8.11616423423967e-10, -1.67305274317960e-09 } }, - { { 5, 1, 6, 3 }, { -1.64913548274895e-09, 1.70894051588900e-10 } }, - { { 5, 1, 8, 3 }, { 5.50878617883651e-02, -1.99531994223259e-03 } }, - { { 7, 1, 8, 3 }, { 2.90052566249363e-09, 2.04564331631174e-09 } }, - { { 1, 3, 2, 3 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 5, 3, 6, 3 }, { 2.77775993160252e-04, 3.77410302057860e-03 } }, - { { 5, 3, 8, 3 }, { -4.67622884853612e-09, -6.98952045795709e-10 } }, - { { 7, 3, 8, 3 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 1, 5, 6, 3 }, { -1.76420137101272e-09, -1.05104052115801e-10 } }, - { { 1, 5, 8, 3 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, - { { 3, 5, 8, 3 }, { -4.05111132068935e-09, 1.17669809910942e-09 } }, - { { 5, 7, 2, 3 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 1, 7, 6, 3 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 3, 7, 6, 3 }, { -7.35799849724064e-10, 8.96392999344636e-10 } }, - { { 1, 7, 8, 3 }, { 2.71542765796015e-09, -1.76543336019022e-09 } }, - { { 3, 7, 8, 3 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 7, 1, 2, 5 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 5, 1, 4, 5 }, { 1.64913548399047e-09, -1.70894048294891e-10 } }, - { { 5, 3, 4, 5 }, { -2.77775993160252e-04, -3.77410302057860e-03 } }, - { { 1, 3, 8, 5 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 3, 5, 2, 5 }, { -7.84227887895554e-10, -8.65456802951857e-10 } }, - { { 1, 5, 4, 5 }, { 1.76420137225424e-09, 1.05104055409810e-10 } }, - { { 1, 7, 4, 5 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 3, 7, 4, 5 }, { 7.35799852035404e-10, -8.96392999081955e-10 } }, - { { 5, 7, 8, 5 }, { 2.10829501478453e-03, -9.24701177434335e-03 } }, - { { 5, 1, 2, 7 }, { -4.07154503624496e-09, 3.34683197320015e-10 } }, - { { 5, 1, 4, 7 }, { -5.50878617883651e-02, 1.99531994223258e-03 } }, - { { 7, 1, 4, 7 }, { -2.90052566280734e-09, -2.04564331648436e-09 } }, - { { 5, 3, 2, 7 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 7, 3, 2, 7 }, { -1.49528281775848e-09, -1.95530142301122e-09 } }, - { { 5, 3, 4, 7 }, { 4.67622884828570e-09, 6.98952045491450e-10 } }, - { { 7, 3, 4, 7 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 1, 3, 6, 7 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 1, 5, 2, 7 }, { -3.44264963011916e-09, 9.90112075686836e-12 } }, - { { 1, 5, 4, 7 }, { -5.50878617767860e-02, 1.99532026191666e-03 } }, - { { 3, 5, 4, 7 }, { 4.05111132035920e-09, -1.17669809883779e-09 } }, - { { 1, 7, 2, 7 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 3, 7, 2, 7 }, { -8.11616426840793e-10, 1.67305273292072e-09 } }, - { { 1, 7, 4, 7 }, { -2.71542765827455e-09, 1.76543336029064e-09 } }, - { { 3, 7, 4, 7 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 5, 7, 6, 7 }, { -2.10829501478453e-03, 9.24701177434334e-03 } }, - { { 1, 1, 2, 2 }, { 2.61972936056406e-01, -5.30213028386074e-17 } }, - { { 3, 1, 2, 2 }, { 1.26743997191602e-09, 9.20431351748613e-12 } }, - { { 1, 1, 4, 2 }, { 1.26743997139537e-09, -9.20430897449278e-12 } }, - { { 3, 1, 4, 2 }, { 2.00381403996136e-02, -1.62630325872826e-18 } }, - { { 5, 1, 6, 2 }, { 7.34497110698912e-02, 2.32390791791556e-17 } }, - { { 7, 1, 6, 2 }, { 3.38241175355620e-09, 2.85419828471446e-09 } }, - { { 5, 1, 8, 2 }, { 3.38241175357191e-09, -2.85419828967186e-09 } }, - { { 7, 1, 8, 2 }, { 1.04255386413001e-02, -2.16840434497101e-19 } }, - { { 1, 3, 2, 2 }, { 1.26743996457650e-09, -9.20429928368850e-12 } }, - { { 3, 3, 2, 2 }, { 2.61943485031872e-01, -1.37722265068768e-17 } }, - { { 3, 3, 4, 2 }, { -1.27168924198546e-09, 9.73022871836289e-12 } }, - { { 5, 3, 6, 2 }, { -4.51615803003425e-09, -1.41887387061851e-09 } }, - { { 7, 3, 6, 2 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, - { { 7, 3, 8, 2 }, { 2.15553000777860e-09, 1.31756361465258e-09 } }, - { { 5, 5, 2, 2 }, { 2.50873194689164e-01, 2.50879550989324e-17 } }, - { { 7, 5, 4, 2 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, - { { 1, 5, 6, 2 }, { 7.34497110698911e-02, -4.26240855372007e-10 } }, - { { 3, 5, 6, 2 }, { -5.63030150072833e-09, 1.78997963434557e-09 } }, - { { 1, 5, 8, 2 }, { 4.01669748488940e-09, -3.60591433236876e-09 } }, - { { 3, 5, 8, 2 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 7, 7, 2, 2 }, { 2.50828949907785e-01, -1.14936844391139e-17 } }, - { { 1, 7, 6, 2 }, { 4.01669748357888e-09, -3.60591431101307e-09 } }, - { { 3, 7, 6, 2 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, - { { 3, 7, 8, 2 }, { -4.28392086691139e-10, -3.43537540225082e-09 } }, - { { 1, 1, 2, 4 }, { 1.26743996509614e-09, 9.20431253262051e-12 } }, - { { 1, 1, 4, 4 }, { 2.61943485031872e-01, -1.12169505428259e-17 } }, - { { 3, 1, 4, 4 }, { -1.27168924251628e-09, -9.73022385794241e-12 } }, - { { 5, 1, 6, 4 }, { -4.51615803040078e-09, 1.41887386923595e-09 } }, - { { 5, 1, 8, 4 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 7, 1, 8, 4 }, { 2.15553000456903e-09, -1.31756361634066e-09 } }, - { { 1, 3, 2, 4 }, { 2.00381403996136e-02, -8.67361737988404e-19 } }, - { { 3, 3, 2, 4 }, { -1.27168924954398e-09, -9.73022416051130e-12 } }, - { { 1, 3, 4, 4 }, { -1.27168924901213e-09, 9.73023776236440e-12 } }, - { { 3, 3, 4, 4 }, { 2.61914049687002e-01, 2.80103420724926e-17 } }, - { { 5, 3, 6, 4 }, { 1.48617254260414e-02, -6.50521303491303e-19 } }, - { { 7, 3, 6, 4 }, { -2.00828744436733e-09, -2.74866710690401e-09 } }, - { { 5, 3, 8, 4 }, { -2.00828744455438e-09, 2.74866710694982e-09 } }, - { { 7, 3, 8, 4 }, { 3.20339000240785e-02, -5.20417042793042e-18 } }, - { { 5, 5, 4, 4 }, { 2.50843627819692e-01, 4.72101682017815e-17 } }, - { { 1, 5, 6, 4 }, { -5.63030148921086e-09, 1.78997963244246e-09 } }, - { { 1, 5, 8, 4 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, - { { 3, 5, 8, 4 }, { -1.11475987598887e-09, 4.36237059368112e-09 } }, - { { 5, 7, 2, 4 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 7, 7, 4, 4 }, { 2.50799402750969e-01, 1.06092925530601e-17 } }, - { { 1, 7, 6, 4 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 3, 7, 6, 4 }, { -1.11475987342053e-09, 4.36237058630139e-09 } }, - { { 1, 7, 8, 4 }, { -4.28392074239289e-10, -3.43537539464995e-09 } }, - { { 3, 7, 8, 4 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, - { { 5, 1, 2, 6 }, { 7.34497110698911e-02, 4.26240884128866e-10 } }, - { { 7, 1, 2, 6 }, { 4.01669748523631e-09, 3.60591432791919e-09 } }, - { { 5, 1, 4, 6 }, { -5.63030150036024e-09, -1.78997964461309e-09 } }, - { { 7, 1, 4, 6 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 1, 1, 6, 6 }, { 2.50873194689164e-01, -3.87204018911796e-18 } }, - { { 3, 1, 8, 6 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 5, 3, 2, 6 }, { -5.63030148956796e-09, -1.78997963400265e-09 } }, - { { 7, 3, 2, 6 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, - { { 7, 3, 4, 6 }, { -1.11475986949617e-09, -4.36237059634356e-09 } }, - { { 3, 3, 6, 6 }, { 2.50843627819692e-01, 1.72941652301881e-17 } }, - { { 1, 5, 2, 6 }, { 7.34497110698912e-02, 5.51778003395311e-18 } }, - { { 3, 5, 2, 6 }, { -4.51615804182034e-09, 1.41887387030459e-09 } }, - { { 1, 5, 4, 6 }, { -4.51615804217584e-09, -1.41887388074977e-09 } }, - { { 3, 5, 4, 6 }, { 1.48617254260414e-02, -1.84314369322536e-18 } }, - { { 5, 5, 6, 6 }, { 2.46623945475382e-01, -4.47440139398777e-18 } }, - { { 7, 5, 8, 6 }, { 1.31792902727351e-02, 4.87890977618477e-19 } }, - { { 1, 7, 2, 6 }, { 3.38241175221570e-09, -2.85419826711785e-09 } }, - { { 3, 7, 2, 6 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 3, 7, 4, 6 }, { -2.00828745395385e-09, 2.74866711051040e-09 } }, - { { 7, 7, 6, 6 }, { 2.46582791504814e-01, -4.25634912984626e-18 } }, - { { 5, 1, 2, 8 }, { 4.01669748356451e-09, 3.60591430698319e-09 } }, - { { 5, 1, 4, 8 }, { 2.22515327441311e-02, 4.31016204922364e-02 } }, - { { 7, 1, 4, 8 }, { -4.28392084504226e-10, 3.43537540051425e-09 } }, - { { 1, 1, 8, 8 }, { 2.50828949907785e-01, -1.24613051726560e-17 } }, - { { 5, 3, 2, 8 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 7, 3, 2, 8 }, { -4.28392072544871e-10, 3.43537539324139e-09 } }, - { { 5, 3, 4, 8 }, { -1.11475987210074e-09, -4.36237058622425e-09 } }, - { { 7, 3, 4, 8 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, - { { 1, 3, 6, 8 }, { 5.62113152593797e-03, 1.41002713662608e-02 } }, - { { 3, 3, 8, 8 }, { 2.50799402750969e-01, 8.69850171916772e-18 } }, - { { 1, 5, 2, 8 }, { 3.38241175256395e-09, 2.85419826359582e-09 } }, - { { 1, 5, 4, 8 }, { 2.22515329942571e-02, 4.31016203631070e-02 } }, - { { 3, 5, 4, 8 }, { -2.00828744859485e-09, -2.74866711314251e-09 } }, - { { 5, 5, 8, 8 }, { 2.46582791504814e-01, 5.87188339049711e-18 } }, - { { 1, 7, 2, 8 }, { 1.04255386413001e-02, 7.58941520739853e-19 } }, - { { 3, 7, 2, 8 }, { 2.15552999194172e-09, -1.31756362203174e-09 } }, - { { 1, 7, 4, 8 }, { 2.15552999465798e-09, 1.31756362057390e-09 } }, - { { 3, 7, 4, 8 }, { 3.20339000240785e-02, -1.73472347597681e-18 } }, - { { 5, 7, 6, 8 }, { 1.31792902727351e-02, -9.21571846612679e-19 } }, - { { 7, 7, 8, 8 }, { 2.46541664704192e-01, 6.08293979259109e-18 } }, - { { 3, 2, 4, 1 }, { -1.29929463938391e-03, 2.71050543121376e-20 } }, - { { 5, 2, 6, 1 }, { -6.12304508882666e-08, -3.19152887970202e-24 } }, - { { 7, 2, 8, 1 }, { -5.39920423655626e-03, 2.16840434497101e-19 } }, - { { 1, 4, 4, 1 }, { 1.29929463938391e-03, 2.03287907341032e-20 } }, - { { 5, 4, 8, 1 }, { 1.86176220289677e-04, 2.27333215595726e-03 } }, - { { 7, 4, 8, 1 }, { -2.29550213538554e-09, 1.68336752118145e-10 } }, - { { 7, 6, 4, 1 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 1, 6, 6, 1 }, { 6.12304508882666e-08, 1.79308951503732e-24 } }, - { { 3, 6, 8, 1 }, { -1.86176220289677e-04, -2.27333215595726e-03 } }, - { { 5, 8, 4, 1 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 1, 8, 8, 1 }, { 5.39920423655626e-03, -3.79470760369927e-19 } }, - { { 3, 8, 8, 1 }, { 2.29550213550629e-09, -1.68336752322676e-10 } }, - { { 3, 2, 2, 3 }, { 1.29929463938391e-03, 6.77626357803440e-20 } }, - { { 7, 2, 6, 3 }, { 1.86176220289677e-04, -2.27333215595725e-03 } }, - { { 7, 2, 8, 3 }, { -2.29550213630685e-09, -1.68336776816198e-10 } }, - { { 1, 4, 2, 3 }, { -1.29929463938391e-03, -7.45388993583784e-20 } }, - { { 5, 4, 6, 3 }, { -9.63632834913280e-04, 3.38813178901720e-20 } }, - { { 7, 4, 6, 3 }, { 1.20329000661327e-09, 2.38730244045649e-10 } }, - { { 5, 4, 8, 3 }, { 1.20329000658700e-09, -2.38730245117277e-10 } }, - { { 7, 4, 8, 3 }, { -4.13705399893557e-02, -4.33680868994202e-19 } }, - { { 7, 6, 2, 3 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 3, 6, 6, 3 }, { 9.63632834913280e-04, -4.74338450462408e-20 } }, - { { 3, 6, 8, 3 }, { -1.20329000743663e-09, 2.38730247620597e-10 } }, - { { 5, 8, 2, 3 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 1, 8, 6, 3 }, { -1.86176220289677e-04, 2.27333215595725e-03 } }, - { { 3, 8, 6, 3 }, { -1.20329000653132e-09, -2.38730243987742e-10 } }, - { { 1, 8, 8, 3 }, { 2.29550212741584e-09, 1.68336768334048e-10 } }, - { { 3, 8, 8, 3 }, { 4.13705399893557e-02, -9.10729824887824e-18 } }, - { { 5, 2, 2, 5 }, { 6.12304508882665e-08, 8.76752829052342e-25 } }, - { { 7, 2, 4, 5 }, { -1.86176220289677e-04, 2.27333215595725e-03 } }, - { { 3, 2, 8, 5 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 5, 4, 4, 5 }, { 9.63632834913280e-04, 2.03287907341032e-20 } }, - { { 7, 4, 4, 5 }, { -1.20329000767507e-09, -2.38730240700292e-10 } }, - { { 1, 4, 8, 5 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 1, 6, 2, 5 }, { -6.12304508882665e-08, 5.21686141181912e-25 } }, - { { 3, 6, 4, 5 }, { -9.63632834913280e-04, 1.35525271560688e-20 } }, - { { 7, 6, 8, 5 }, { -6.82529157237476e-03, 1.08420217248550e-19 } }, - { { 1, 8, 4, 5 }, { 1.86176220289677e-04, -2.27333215595725e-03 } }, - { { 3, 8, 4, 5 }, { 1.20329000759312e-09, 2.38730240642386e-10 } }, - { { 5, 8, 8, 5 }, { 6.82529157237476e-03, 2.71050543121376e-19 } }, - { { 7, 2, 2, 7 }, { 5.39920423655626e-03, -0.00000000000000e+00 } }, - { { 7, 2, 4, 7 }, { 2.29550213669100e-09, 1.68336776889122e-10 } }, - { { 3, 2, 6, 7 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 5, 4, 2, 7 }, { -1.86176220289677e-04, -2.27333215595725e-03 } }, - { { 7, 4, 2, 7 }, { 2.29550212639229e-09, -1.68336740827533e-10 } }, - { { 5, 4, 4, 7 }, { -1.20329000656955e-09, 2.38730244953007e-10 } }, - { { 7, 4, 4, 7 }, { 4.13705399893557e-02, -3.25260651745651e-18 } }, - { { 1, 4, 6, 7 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 3, 6, 2, 7 }, { 1.86176220289677e-04, 2.27333215595725e-03 } }, - { { 3, 6, 4, 7 }, { 1.20329000741918e-09, -2.38730247456327e-10 } }, - { { 7, 6, 6, 7 }, { 6.82529157237476e-03, -4.87890977618477e-19 } }, - { { 1, 8, 2, 7 }, { -5.39920423655626e-03, 2.16840434497101e-19 } }, - { { 3, 8, 2, 7 }, { -2.29550212651305e-09, 1.68336741032063e-10 } }, - { { 1, 8, 4, 7 }, { -2.29550212779999e-09, -1.68336768406972e-10 } }, - { { 3, 8, 4, 7 }, { -4.13705399893557e-02, 1.23599047663348e-17 } }, - { { 5, 8, 6, 7 }, { -6.82529157237476e-03, -5.42101086242752e-20 } }, - { { 7, 2, 6, 2 }, { -4.07154503617311e-09, -3.34683197652399e-10 } }, - { { 5, 2, 8, 2 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 5, 4, 6, 2 }, { 1.64913548384803e-09, 1.70894048276102e-10 } }, - { { 7, 4, 6, 2 }, { -5.50878617883651e-02, -1.99531994223259e-03 } }, - { { 7, 4, 8, 2 }, { -2.90052566130477e-09, 2.04564330064451e-09 } }, - { { 3, 6, 6, 2 }, { -1.64913548260651e-09, -1.70894051570111e-10 } }, - { { 1, 6, 8, 2 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 1, 8, 6, 2 }, { 4.07154504759461e-09, 3.34683209358053e-10 } }, - { { 3, 8, 6, 2 }, { 5.50878617883651e-02, 1.99531994223260e-03 } }, - { { 3, 8, 8, 2 }, { 2.90052566099105e-09, -2.04564330047190e-09 } }, - { { 3, 2, 2, 4 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 7, 2, 6, 4 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 7, 2, 8, 4 }, { -1.49528281786713e-09, 1.95530142297282e-09 } }, - { { 1, 4, 2, 4 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 5, 4, 6, 4 }, { -2.77775993160253e-04, 3.77410302057860e-03 } }, - { { 7, 4, 6, 4 }, { 4.67622885713219e-09, -6.98952053111356e-10 } }, - { { 7, 4, 8, 4 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 7, 6, 2, 4 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 3, 6, 6, 4 }, { 2.77775993160253e-04, -3.77410302057860e-03 } }, - { { 5, 8, 2, 4 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 1, 8, 6, 4 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 3, 8, 6, 4 }, { -4.67622885738260e-09, 6.98952053415614e-10 } }, - { { 1, 8, 8, 4 }, { 1.49528282820932e-09, -1.95530142612850e-09 } }, - { { 3, 8, 8, 4 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 7, 2, 2, 6 }, { -3.44264963006675e-09, -9.90112058323764e-12 } }, - { { 5, 2, 4, 6 }, { -7.84227887895553e-10, 8.65456802951857e-10 } }, - { { 5, 4, 2, 6 }, { 1.76420137232554e-09, -1.05104055437868e-10 } }, - { { 7, 4, 2, 6 }, { -5.50878617767860e-02, -1.99532026191665e-03 } }, - { { 7, 4, 4, 6 }, { 4.05111131184309e-09, 1.17669809730382e-09 } }, - { { 3, 6, 2, 6 }, { -1.76420137108402e-09, 1.05104052143859e-10 } }, - { { 1, 6, 4, 6 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, - { { 1, 8, 2, 6 }, { 3.44264964148825e-09, 9.90113228889187e-12 } }, - { { 3, 8, 2, 6 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, - { { 3, 8, 4, 6 }, { -4.05111131217324e-09, -1.17669809757545e-09 } }, - { { 7, 2, 2, 8 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 7, 2, 4, 8 }, { -8.11616426817687e-10, -1.67305273280271e-09 } }, - { { 3, 2, 6, 8 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 5, 4, 2, 8 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 7, 4, 2, 8 }, { -2.71542765860322e-09, -1.76543337688875e-09 } }, - { { 5, 4, 4, 8 }, { 7.35799852084301e-10, 8.96392999068158e-10 } }, - { { 7, 4, 4, 8 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 1, 4, 6, 8 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 3, 6, 2, 8 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 3, 6, 4, 8 }, { -7.35799849772961e-10, -8.96392999330838e-10 } }, - { { 7, 6, 6, 8 }, { -2.10829501478453e-03, -9.24701177434335e-03 } }, - { { 1, 8, 2, 8 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 3, 8, 2, 8 }, { 2.71542765828882e-09, 1.76543337678833e-09 } }, - { { 1, 8, 4, 8 }, { 8.11616423400861e-10, 1.67305274306159e-09 } }, - { { 3, 8, 4, 8 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 5, 8, 6, 8 }, { 2.10829501478453e-03, 9.24701177434334e-03 } }, - { { 8, 1, 5, 1 }, { 4.07154504766646e-09, -3.34683209025669e-10 } }, - { { 6, 1, 7, 1 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 6, 3, 5, 1 }, { -1.64913548274895e-09, 1.70894051588900e-10 } }, - { { 8, 3, 5, 1 }, { 5.50878617883651e-02, -1.99531994223259e-03 } }, - { { 8, 3, 7, 1 }, { 2.90052566249363e-09, 2.04564331631174e-09 } }, - { { 4, 5, 5, 1 }, { 1.64913548399047e-09, -1.70894048294891e-10 } }, - { { 2, 5, 7, 1 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 2, 7, 5, 1 }, { -4.07154503624496e-09, 3.34683197320015e-10 } }, - { { 4, 7, 5, 1 }, { -5.50878617883651e-02, 1.99531994223258e-03 } }, - { { 4, 7, 7, 1 }, { -2.90052566280734e-09, -2.04564331648436e-09 } }, - { { 4, 1, 1, 3 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 8, 1, 5, 3 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 8, 1, 7, 3 }, { 1.49528282810068e-09, 1.95530142616690e-09 } }, - { { 2, 3, 1, 3 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 6, 3, 5, 3 }, { 2.77775993160252e-04, 3.77410302057860e-03 } }, - { { 8, 3, 5, 3 }, { -4.67622884853612e-09, -6.98952045795709e-10 } }, - { { 8, 3, 7, 3 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 8, 5, 1, 3 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 4, 5, 5, 3 }, { -2.77775993160252e-04, -3.77410302057860e-03 } }, - { { 6, 7, 1, 3 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 2, 7, 5, 3 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 4, 7, 5, 3 }, { 4.67622884828570e-09, 6.98952045491450e-10 } }, - { { 2, 7, 7, 3 }, { -1.49528281775848e-09, -1.95530142301122e-09 } }, - { { 4, 7, 7, 3 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 8, 1, 1, 5 }, { 3.44264964154066e-09, -9.90113246252263e-12 } }, - { { 6, 1, 3, 5 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, - { { 6, 3, 1, 5 }, { -1.76420137101272e-09, -1.05104052115801e-10 } }, - { { 8, 3, 1, 5 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, - { { 8, 3, 3, 5 }, { -4.05111132068935e-09, 1.17669809910942e-09 } }, - { { 4, 5, 1, 5 }, { 1.76420137225424e-09, 1.05104055409810e-10 } }, - { { 2, 5, 3, 5 }, { -7.84227887895554e-10, -8.65456802951857e-10 } }, - { { 2, 7, 1, 5 }, { -3.44264963011916e-09, 9.90112075686836e-12 } }, - { { 4, 7, 1, 5 }, { -5.50878617767860e-02, 1.99532026191666e-03 } }, - { { 4, 7, 3, 5 }, { 4.05111132035920e-09, -1.17669809883779e-09 } }, - { { 8, 1, 1, 7 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 8, 1, 3, 7 }, { 8.11616423423967e-10, -1.67305274317960e-09 } }, - { { 4, 1, 5, 7 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 6, 3, 1, 7 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 8, 3, 1, 7 }, { 2.71542765796015e-09, -1.76543336019022e-09 } }, - { { 6, 3, 3, 7 }, { -7.35799849724064e-10, 8.96392999344636e-10 } }, - { { 8, 3, 3, 7 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 2, 3, 5, 7 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 4, 5, 1, 7 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 4, 5, 3, 7 }, { 7.35799852035404e-10, -8.96392999081955e-10 } }, - { { 8, 5, 5, 7 }, { 2.10829501478453e-03, -9.24701177434335e-03 } }, - { { 2, 7, 1, 7 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 4, 7, 1, 7 }, { -2.71542765827455e-09, 1.76543336029064e-09 } }, - { { 2, 7, 3, 7 }, { -8.11616426840793e-10, 1.67305273292072e-09 } }, - { { 4, 7, 3, 7 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 6, 7, 5, 7 }, { -2.10829501478453e-03, 9.24701177434334e-03 } }, - { { 4, 1, 3, 2 }, { -1.29929463938391e-03, -2.71050543121376e-20 } }, - { { 6, 1, 5, 2 }, { -6.12304508882666e-08, 3.19152887970202e-24 } }, - { { 8, 1, 7, 2 }, { -5.39920423655626e-03, -2.16840434497101e-19 } }, - { { 2, 3, 3, 2 }, { 1.29929463938391e-03, -2.03287907341032e-20 } }, - { { 6, 3, 7, 2 }, { 1.86176220289677e-04, -2.27333215595726e-03 } }, - { { 8, 3, 7, 2 }, { -2.29550213538554e-09, -1.68336752118145e-10 } }, - { { 8, 5, 3, 2 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 2, 5, 5, 2 }, { 6.12304508882666e-08, -1.79308951503732e-24 } }, - { { 4, 5, 7, 2 }, { -1.86176220289677e-04, 2.27333215595726e-03 } }, - { { 6, 7, 3, 2 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 2, 7, 7, 2 }, { 5.39920423655626e-03, 3.79470760369927e-19 } }, - { { 4, 7, 7, 2 }, { 2.29550213550629e-09, 1.68336752322676e-10 } }, - { { 4, 1, 1, 4 }, { 1.29929463938391e-03, -6.77626357803440e-20 } }, - { { 8, 1, 5, 4 }, { 1.86176220289677e-04, 2.27333215595725e-03 } }, - { { 8, 1, 7, 4 }, { -2.29550213630685e-09, 1.68336776816198e-10 } }, - { { 2, 3, 1, 4 }, { -1.29929463938391e-03, 7.45388993583784e-20 } }, - { { 6, 3, 5, 4 }, { -9.63632834913280e-04, -3.38813178901720e-20 } }, - { { 8, 3, 5, 4 }, { 1.20329000661327e-09, -2.38730244045649e-10 } }, - { { 6, 3, 7, 4 }, { 1.20329000658700e-09, 2.38730245117277e-10 } }, - { { 8, 3, 7, 4 }, { -4.13705399893557e-02, 4.33680868994202e-19 } }, - { { 8, 5, 1, 4 }, { 2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 4, 5, 5, 4 }, { 9.63632834913280e-04, 4.74338450462408e-20 } }, - { { 4, 5, 7, 4 }, { -1.20329000743663e-09, -2.38730247620597e-10 } }, - { { 6, 7, 1, 4 }, { -2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 2, 7, 5, 4 }, { -1.86176220289677e-04, -2.27333215595725e-03 } }, - { { 4, 7, 5, 4 }, { -1.20329000653132e-09, 2.38730243987742e-10 } }, - { { 2, 7, 7, 4 }, { 2.29550212741584e-09, -1.68336768334048e-10 } }, - { { 4, 7, 7, 4 }, { 4.13705399893557e-02, 9.10729824887824e-18 } }, - { { 6, 1, 1, 6 }, { 6.12304508882665e-08, -8.76752829052342e-25 } }, - { { 8, 1, 3, 6 }, { -1.86176220289677e-04, -2.27333215595725e-03 } }, - { { 4, 1, 7, 6 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 6, 3, 3, 6 }, { 9.63632834913280e-04, -2.03287907341032e-20 } }, - { { 8, 3, 3, 6 }, { -1.20329000767507e-09, 2.38730240700292e-10 } }, - { { 2, 3, 7, 6 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 2, 5, 1, 6 }, { -6.12304508882665e-08, -5.21686141181912e-25 } }, - { { 4, 5, 3, 6 }, { -9.63632834913280e-04, -1.35525271560688e-20 } }, - { { 8, 5, 7, 6 }, { -6.82529157237476e-03, -1.08420217248550e-19 } }, - { { 2, 7, 3, 6 }, { 1.86176220289677e-04, 2.27333215595725e-03 } }, - { { 4, 7, 3, 6 }, { 1.20329000759312e-09, -2.38730240642386e-10 } }, - { { 6, 7, 7, 6 }, { 6.82529157237476e-03, -2.71050543121376e-19 } }, - { { 8, 1, 1, 8 }, { 5.39920423655626e-03, 0.00000000000000e+00 } }, - { { 8, 1, 3, 8 }, { 2.29550213669100e-09, -1.68336776889122e-10 } }, - { { 4, 1, 5, 8 }, { 2.27038272905574e-04, -2.77226111683749e-03 } }, - { { 6, 3, 1, 8 }, { -1.86176220289677e-04, 2.27333215595725e-03 } }, - { { 8, 3, 1, 8 }, { 2.29550212639229e-09, 1.68336740827533e-10 } }, - { { 6, 3, 3, 8 }, { -1.20329000656955e-09, -2.38730244953007e-10 } }, - { { 8, 3, 3, 8 }, { 4.13705399893557e-02, 3.25260651745651e-18 } }, - { { 2, 3, 5, 8 }, { -2.27038272905574e-04, 2.77226111683749e-03 } }, - { { 4, 5, 1, 8 }, { 1.86176220289677e-04, -2.27333215595725e-03 } }, - { { 4, 5, 3, 8 }, { 1.20329000741918e-09, 2.38730247456327e-10 } }, - { { 8, 5, 5, 8 }, { 6.82529157237476e-03, 4.87890977618477e-19 } }, - { { 2, 7, 1, 8 }, { -5.39920423655626e-03, -2.16840434497101e-19 } }, - { { 4, 7, 1, 8 }, { -2.29550212651305e-09, -1.68336741032063e-10 } }, - { { 2, 7, 3, 8 }, { -2.29550212779999e-09, 1.68336768406972e-10 } }, - { { 4, 7, 3, 8 }, { -4.13705399893557e-02, -1.23599047663348e-17 } }, - { { 6, 7, 5, 8 }, { -6.82529157237476e-03, 5.42101086242752e-20 } }, - { { 2, 2, 1, 1 }, { 2.61972936056406e-01, 5.30213028386074e-17 } }, - { { 4, 2, 1, 1 }, { 1.26743997191602e-09, -9.20431351748613e-12 } }, - { { 2, 2, 3, 1 }, { 1.26743997139537e-09, 9.20430897449278e-12 } }, - { { 4, 2, 3, 1 }, { 2.00381403996136e-02, 1.62630325872826e-18 } }, - { { 6, 2, 5, 1 }, { 7.34497110698912e-02, -2.32390791791556e-17 } }, - { { 8, 2, 5, 1 }, { 3.38241175355620e-09, -2.85419828471446e-09 } }, - { { 6, 2, 7, 1 }, { 3.38241175357191e-09, 2.85419828967186e-09 } }, - { { 8, 2, 7, 1 }, { 1.04255386413001e-02, 2.16840434497101e-19 } }, - { { 2, 4, 1, 1 }, { 1.26743996457650e-09, 9.20429928368850e-12 } }, - { { 4, 4, 1, 1 }, { 2.61943485031872e-01, 1.37722265068768e-17 } }, - { { 4, 4, 3, 1 }, { -1.27168924198546e-09, -9.73022871836289e-12 } }, - { { 6, 4, 5, 1 }, { -4.51615803003425e-09, 1.41887387061851e-09 } }, - { { 8, 4, 5, 1 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 8, 4, 7, 1 }, { 2.15553000777860e-09, -1.31756361465258e-09 } }, - { { 6, 6, 1, 1 }, { 2.50873194689164e-01, -2.50879550989324e-17 } }, - { { 8, 6, 3, 1 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 2, 6, 5, 1 }, { 7.34497110698911e-02, 4.26240855372007e-10 } }, - { { 4, 6, 5, 1 }, { -5.63030150072833e-09, -1.78997963434557e-09 } }, - { { 2, 6, 7, 1 }, { 4.01669748488940e-09, 3.60591433236876e-09 } }, - { { 4, 6, 7, 1 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 8, 8, 1, 1 }, { 2.50828949907785e-01, 1.14936844391139e-17 } }, - { { 2, 8, 5, 1 }, { 4.01669748357888e-09, 3.60591431101307e-09 } }, - { { 4, 8, 5, 1 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, - { { 4, 8, 7, 1 }, { -4.28392086691139e-10, 3.43537540225082e-09 } }, - { { 2, 2, 1, 3 }, { 1.26743996509614e-09, -9.20431253262051e-12 } }, - { { 2, 2, 3, 3 }, { 2.61943485031872e-01, 1.12169505428259e-17 } }, - { { 4, 2, 3, 3 }, { -1.27168924251628e-09, 9.73022385794241e-12 } }, - { { 6, 2, 5, 3 }, { -4.51615803040078e-09, -1.41887386923595e-09 } }, - { { 6, 2, 7, 3 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, - { { 8, 2, 7, 3 }, { 2.15553000456903e-09, 1.31756361634066e-09 } }, - { { 2, 4, 1, 3 }, { 2.00381403996136e-02, 8.67361737988404e-19 } }, - { { 4, 4, 1, 3 }, { -1.27168924954398e-09, 9.73022416051130e-12 } }, - { { 2, 4, 3, 3 }, { -1.27168924901213e-09, -9.73023776236440e-12 } }, - { { 4, 4, 3, 3 }, { 2.61914049687002e-01, -2.80103420724926e-17 } }, - { { 6, 4, 5, 3 }, { 1.48617254260414e-02, 6.50521303491303e-19 } }, - { { 8, 4, 5, 3 }, { -2.00828744436733e-09, 2.74866710690401e-09 } }, - { { 6, 4, 7, 3 }, { -2.00828744455438e-09, -2.74866710694982e-09 } }, - { { 8, 4, 7, 3 }, { 3.20339000240785e-02, 5.20417042793042e-18 } }, - { { 6, 6, 3, 3 }, { 2.50843627819692e-01, -4.72101682017815e-17 } }, - { { 2, 6, 5, 3 }, { -5.63030148921086e-09, -1.78997963244246e-09 } }, - { { 2, 6, 7, 3 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, - { { 4, 6, 7, 3 }, { -1.11475987598887e-09, -4.36237059368112e-09 } }, - { { 6, 8, 1, 3 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, - { { 8, 8, 3, 3 }, { 2.50799402750969e-01, -1.06092925530601e-17 } }, - { { 2, 8, 5, 3 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 4, 8, 5, 3 }, { -1.11475987342053e-09, -4.36237058630139e-09 } }, - { { 2, 8, 7, 3 }, { -4.28392074239289e-10, 3.43537539464995e-09 } }, - { { 4, 8, 7, 3 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, - { { 6, 2, 1, 5 }, { 7.34497110698911e-02, -4.26240884128866e-10 } }, - { { 8, 2, 1, 5 }, { 4.01669748523631e-09, -3.60591432791919e-09 } }, - { { 6, 2, 3, 5 }, { -5.63030150036024e-09, 1.78997964461309e-09 } }, - { { 8, 2, 3, 5 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 2, 2, 5, 5 }, { 2.50873194689164e-01, 3.87204018911796e-18 } }, - { { 4, 2, 7, 5 }, { 5.62113152593796e-03, 1.41002713662608e-02 } }, - { { 6, 4, 1, 5 }, { -5.63030148956796e-09, 1.78997963400265e-09 } }, - { { 8, 4, 1, 5 }, { 2.22515327441311e-02, -4.31016204922363e-02 } }, - { { 8, 4, 3, 5 }, { -1.11475986949617e-09, 4.36237059634356e-09 } }, - { { 4, 4, 5, 5 }, { 2.50843627819692e-01, -1.72941652301881e-17 } }, - { { 2, 6, 1, 5 }, { 7.34497110698912e-02, -5.51778003395311e-18 } }, - { { 4, 6, 1, 5 }, { -4.51615804182034e-09, -1.41887387030459e-09 } }, - { { 2, 6, 3, 5 }, { -4.51615804217584e-09, 1.41887388074977e-09 } }, - { { 4, 6, 3, 5 }, { 1.48617254260414e-02, 1.84314369322536e-18 } }, - { { 6, 6, 5, 5 }, { 2.46623945475382e-01, 4.47440139398777e-18 } }, - { { 8, 6, 7, 5 }, { 1.31792902727351e-02, -4.87890977618477e-19 } }, - { { 2, 8, 1, 5 }, { 3.38241175221570e-09, 2.85419826711785e-09 } }, - { { 4, 8, 1, 5 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, - { { 4, 8, 3, 5 }, { -2.00828745395385e-09, -2.74866711051040e-09 } }, - { { 8, 8, 5, 5 }, { 2.46582791504814e-01, 4.25634912984626e-18 } }, - { { 6, 2, 1, 7 }, { 4.01669748356451e-09, -3.60591430698319e-09 } }, - { { 6, 2, 3, 7 }, { 2.22515327441311e-02, -4.31016204922364e-02 } }, - { { 8, 2, 3, 7 }, { -4.28392084504226e-10, -3.43537540051425e-09 } }, - { { 2, 2, 7, 7 }, { 2.50828949907785e-01, 1.24613051726560e-17 } }, - { { 6, 4, 1, 7 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 8, 4, 1, 7 }, { -4.28392072544871e-10, -3.43537539324139e-09 } }, - { { 6, 4, 3, 7 }, { -1.11475987210074e-09, 4.36237058622425e-09 } }, - { { 8, 4, 3, 7 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, - { { 2, 4, 5, 7 }, { 5.62113152593797e-03, -1.41002713662608e-02 } }, - { { 4, 4, 7, 7 }, { 2.50799402750969e-01, -8.69850171916772e-18 } }, - { { 2, 6, 1, 7 }, { 3.38241175256395e-09, -2.85419826359582e-09 } }, - { { 2, 6, 3, 7 }, { 2.22515329942571e-02, -4.31016203631070e-02 } }, - { { 4, 6, 3, 7 }, { -2.00828744859485e-09, 2.74866711314251e-09 } }, - { { 6, 6, 7, 7 }, { 2.46582791504814e-01, -5.87188339049711e-18 } }, - { { 2, 8, 1, 7 }, { 1.04255386413001e-02, -7.58941520739853e-19 } }, - { { 4, 8, 1, 7 }, { 2.15552999194172e-09, 1.31756362203174e-09 } }, - { { 2, 8, 3, 7 }, { 2.15552999465798e-09, -1.31756362057390e-09 } }, - { { 4, 8, 3, 7 }, { 3.20339000240785e-02, 1.73472347597681e-18 } }, - { { 6, 8, 5, 7 }, { 1.31792902727351e-02, 9.21571846612679e-19 } }, - { { 8, 8, 7, 7 }, { 2.46541664704192e-01, -6.08293979259109e-18 } }, - { { 8, 2, 5, 2 }, { 2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 6, 2, 7, 2 }, { -4.07154503617311e-09, -3.34683197652399e-10 } }, - { { 2, 4, 3, 2 }, { 3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 6, 4, 7, 2 }, { -8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 8, 4, 7, 2 }, { -1.49528281786713e-09, 1.95530142297282e-09 } }, - { { 4, 6, 5, 2 }, { -7.84227887895553e-10, 8.65456802951857e-10 } }, - { { 2, 6, 7, 2 }, { -3.44264963006675e-09, -9.90112058323764e-12 } }, - { { 6, 8, 3, 2 }, { 3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 2, 8, 7, 2 }, { -1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 4, 8, 7, 2 }, { -8.11616426817687e-10, -1.67305273280271e-09 } }, - { { 6, 2, 5, 4 }, { 1.64913548384803e-09, 1.70894048276102e-10 } }, - { { 6, 2, 7, 4 }, { -5.50878617883651e-02, -1.99531994223259e-03 } }, - { { 8, 2, 7, 4 }, { -2.90052566130477e-09, 2.04564330064451e-09 } }, - { { 2, 4, 1, 4 }, { -3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 6, 4, 5, 4 }, { -2.77775993160253e-04, 3.77410302057860e-03 } }, - { { 6, 4, 7, 4 }, { 4.67622885713219e-09, -6.98952053111356e-10 } }, - { { 8, 4, 7, 4 }, { -1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 2, 6, 5, 4 }, { 1.76420137232554e-09, -1.05104055437868e-10 } }, - { { 2, 6, 7, 4 }, { -5.50878617767860e-02, -1.99532026191665e-03 } }, - { { 4, 6, 7, 4 }, { 4.05111131184309e-09, 1.17669809730382e-09 } }, - { { 6, 8, 1, 4 }, { -3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 2, 8, 5, 4 }, { -3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 4, 8, 5, 4 }, { 7.35799852084301e-10, 8.96392999068158e-10 } }, - { { 2, 8, 7, 4 }, { -2.71542765860322e-09, -1.76543337688875e-09 } }, - { { 4, 8, 7, 4 }, { -1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 8, 2, 1, 6 }, { -2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 6, 2, 3, 6 }, { -1.64913548260651e-09, -1.70894051570111e-10 } }, - { { 6, 4, 3, 6 }, { 2.77775993160253e-04, -3.77410302057860e-03 } }, - { { 2, 4, 7, 6 }, { -1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 4, 6, 1, 6 }, { 7.84227887895553e-10, -8.65456802951857e-10 } }, - { { 2, 6, 3, 6 }, { -1.76420137108402e-09, 1.05104052143859e-10 } }, - { { 2, 8, 3, 6 }, { 3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 4, 8, 3, 6 }, { -7.35799849772961e-10, -8.96392999330838e-10 } }, - { { 6, 8, 7, 6 }, { -2.10829501478453e-03, -9.24701177434335e-03 } }, - { { 6, 2, 1, 8 }, { 4.07154504759461e-09, 3.34683209358053e-10 } }, - { { 6, 2, 3, 8 }, { 5.50878617883651e-02, 1.99531994223260e-03 } }, - { { 8, 2, 3, 8 }, { 2.90052566099105e-09, -2.04564330047190e-09 } }, - { { 6, 4, 1, 8 }, { 8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 8, 4, 1, 8 }, { 1.49528282820932e-09, -1.95530142612850e-09 } }, - { { 6, 4, 3, 8 }, { -4.67622885738260e-09, 6.98952053415614e-10 } }, - { { 8, 4, 3, 8 }, { 1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 2, 4, 5, 8 }, { 1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 2, 6, 1, 8 }, { 3.44264964148825e-09, 9.90113228889187e-12 } }, - { { 2, 6, 3, 8 }, { 5.50878617767860e-02, 1.99532026191667e-03 } }, - { { 4, 6, 3, 8 }, { -4.05111131217324e-09, -1.17669809757545e-09 } }, - { { 2, 8, 1, 8 }, { 1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 4, 8, 1, 8 }, { 8.11616423400861e-10, 1.67305274306159e-09 } }, - { { 2, 8, 3, 8 }, { 2.71542765828882e-09, 1.76543337678833e-09 } }, - { { 4, 8, 3, 8 }, { 1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 6, 8, 5, 8 }, { 2.10829501478453e-03, 9.24701177434334e-03 } }, - { { 8, 1, 6, 1 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 6, 1, 8, 1 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 6, 3, 6, 1 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 8, 3, 8, 1 }, { 2.62531674824712e-09, -3.02224836883949e-10 } }, - { { 4, 5, 6, 1 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 2, 5, 8, 1 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 2, 7, 6, 1 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 4, 7, 8, 1 }, { -2.62531674833921e-09, 3.02224836559841e-10 } }, - { { 6, 1, 6, 3 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 8, 1, 8, 3 }, { 2.62531674824712e-09, -3.02224836883949e-10 } }, - { { 8, 3, 6, 3 }, { -1.24277413581665e-09, -5.61668439388257e-12 } }, - { { 6, 3, 8, 3 }, { -1.24277413581665e-09, -5.61668439388257e-12 } }, - { { 8, 3, 8, 3 }, { 4.12621310432840e-02, -2.99301196790540e-03 } }, - { { 2, 5, 6, 3 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 4, 5, 8, 3 }, { 1.24277413499966e-09, 5.61668780729011e-12 } }, - { { 4, 7, 6, 3 }, { 1.24277413595630e-09, 5.61668436628098e-12 } }, - { { 2, 7, 8, 3 }, { -2.62531675639996e-09, 3.02224848795605e-10 } }, - { { 4, 7, 8, 3 }, { -4.12621310432840e-02, 2.99301196790539e-03 } }, - { { 8, 1, 2, 5 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 6, 1, 4, 5 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 6, 3, 2, 5 }, { -3.16358063029856e-09, 3.32098371230685e-09 } }, - { { 8, 3, 4, 5 }, { 1.24277413499966e-09, 5.61668780729011e-12 } }, - { { 4, 5, 2, 5 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 2, 5, 4, 5 }, { 3.16358063029856e-09, -3.32098371230685e-09 } }, - { { 2, 7, 2, 5 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 4, 7, 4, 5 }, { -1.24277413513931e-09, -5.61668777968849e-12 } }, - { { 6, 1, 2, 7 }, { 1.93578720630034e-08, 4.21730899777014e-08 } }, - { { 8, 1, 4, 7 }, { -2.62531674833921e-09, 3.02224836559841e-10 } }, - { { 8, 3, 2, 7 }, { -2.62531675639996e-09, 3.02224848795605e-10 } }, - { { 6, 3, 4, 7 }, { 1.24277413595630e-09, 5.61668436628098e-12 } }, - { { 8, 3, 4, 7 }, { -4.12621310432840e-02, 2.99301196790539e-03 } }, - { { 2, 5, 2, 7 }, { -1.93578720630034e-08, -4.21730899777014e-08 } }, - { { 4, 5, 4, 7 }, { -1.24277413513931e-09, -5.61668777968849e-12 } }, - { { 4, 7, 2, 7 }, { 2.62531675649206e-09, -3.02224848471497e-10 } }, - { { 2, 7, 4, 7 }, { 2.62531675649206e-09, -3.02224848471497e-10 } }, - { { 4, 7, 4, 7 }, { 4.12621310432840e-02, -2.99301196790539e-03 } }, - { { 4, 1, 4, 2 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 8, 1, 6, 2 }, { 3.44264964148825e-09, -9.90113228889187e-12 } }, - { { 8, 1, 8, 2 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 2, 3, 4, 2 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 6, 3, 6, 2 }, { -1.76420137108402e-09, -1.05104052143859e-10 } }, - { { 8, 3, 6, 2 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, - { { 6, 3, 8, 2 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 8, 3, 8, 2 }, { 2.71542765828882e-09, -1.76543337678833e-09 } }, - { { 8, 5, 4, 2 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 4, 5, 6, 2 }, { 1.76420137232554e-09, 1.05104055437868e-10 } }, - { { 4, 5, 8, 2 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 6, 7, 4, 2 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 2, 7, 6, 2 }, { -3.44264963006675e-09, 9.90112058323764e-12 } }, - { { 4, 7, 6, 2 }, { -5.50878617767860e-02, 1.99532026191665e-03 } }, - { { 2, 7, 8, 2 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 4, 7, 8, 2 }, { -2.71542765860322e-09, 1.76543337688875e-09 } }, - { { 6, 1, 6, 4 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, - { { 8, 1, 8, 4 }, { 8.11616423400861e-10, -1.67305274306159e-09 } }, - { { 8, 3, 6, 4 }, { -4.05111131217324e-09, 1.17669809757545e-09 } }, - { { 6, 3, 8, 4 }, { -7.35799849772961e-10, 8.96392999330838e-10 } }, - { { 8, 3, 8, 4 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 2, 5, 6, 4 }, { -7.84227887895553e-10, -8.65456802951857e-10 } }, - { { 4, 5, 8, 4 }, { 7.35799852084301e-10, -8.96392999068158e-10 } }, - { { 4, 7, 6, 4 }, { 4.05111131184309e-09, -1.17669809730382e-09 } }, - { { 2, 7, 8, 4 }, { -8.11616426817687e-10, 1.67305273280271e-09 } }, - { { 4, 7, 8, 4 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 8, 1, 2, 6 }, { 4.07154504759461e-09, -3.34683209358053e-10 } }, - { { 8, 1, 4, 6 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 4, 1, 8, 6 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 6, 3, 2, 6 }, { -1.64913548260651e-09, 1.70894051570111e-10 } }, - { { 8, 3, 2, 6 }, { 5.50878617883651e-02, -1.99531994223260e-03 } }, - { { 6, 3, 4, 6 }, { 2.77775993160253e-04, 3.77410302057860e-03 } }, - { { 8, 3, 4, 6 }, { -4.67622885738260e-09, -6.98952053415614e-10 } }, - { { 2, 3, 8, 6 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 4, 5, 2, 6 }, { 1.64913548384803e-09, -1.70894048276102e-10 } }, - { { 4, 5, 4, 6 }, { -2.77775993160253e-04, -3.77410302057860e-03 } }, - { { 8, 5, 8, 6 }, { 2.10829501478453e-03, -9.24701177434334e-03 } }, - { { 2, 7, 2, 6 }, { -4.07154503617311e-09, 3.34683197652399e-10 } }, - { { 4, 7, 2, 6 }, { -5.50878617883651e-02, 1.99531994223259e-03 } }, - { { 2, 7, 4, 6 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 4, 7, 4, 6 }, { 4.67622885713219e-09, 6.98952053111356e-10 } }, - { { 6, 7, 8, 6 }, { -2.10829501478453e-03, 9.24701177434335e-03 } }, - { { 6, 1, 2, 8 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 8, 1, 4, 8 }, { 1.49528282820932e-09, 1.95530142612850e-09 } }, - { { 8, 3, 2, 8 }, { 2.90052566099105e-09, 2.04564330047190e-09 } }, - { { 8, 3, 4, 8 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 2, 5, 2, 8 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 4, 7, 2, 8 }, { -2.90052566130477e-09, -2.04564330064451e-09 } }, - { { 2, 7, 4, 8 }, { -1.49528281786713e-09, -1.95530142297282e-09 } }, - { { 4, 7, 4, 8 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 4, 2, 4, 1 }, { -3.74526321335435e-04, -5.08863600688620e-03 } }, - { { 6, 2, 8, 1 }, { 3.44264964148825e-09, -9.90113228889187e-12 } }, - { { 8, 2, 8, 1 }, { 1.66776801001724e-03, -7.31485409650012e-03 } }, - { { 6, 4, 6, 1 }, { 7.84227887895553e-10, 8.65456802951857e-10 } }, - { { 8, 4, 8, 1 }, { 8.11616423400861e-10, -1.67305274306159e-09 } }, - { { 8, 6, 4, 1 }, { -3.68581034345984e-03, -1.16392983008537e-03 } }, - { { 2, 6, 8, 1 }, { 4.07154504759461e-09, -3.34683209358053e-10 } }, - { { 4, 6, 8, 1 }, { 8.85008772454983e-03, -1.38448609718686e-03 } }, - { { 2, 8, 6, 1 }, { -2.64933414192676e-08, 2.03285723876681e-08 } }, - { { 4, 8, 8, 1 }, { 1.49528282820932e-09, 1.95530142612850e-09 } }, - { { 4, 2, 2, 3 }, { 3.74526321335435e-04, 5.08863600688620e-03 } }, - { { 6, 2, 6, 3 }, { -1.76420137108402e-09, -1.05104052143859e-10 } }, - { { 8, 2, 6, 3 }, { 3.02246152287104e-03, 9.54454245082383e-04 } }, - { { 6, 2, 8, 3 }, { 5.50878617767860e-02, -1.99532026191667e-03 } }, - { { 8, 2, 8, 3 }, { 2.71542765828882e-09, -1.76543337678833e-09 } }, - { { 8, 4, 6, 3 }, { -7.35799849772961e-10, 8.96392999330838e-10 } }, - { { 6, 4, 8, 3 }, { -4.05111131217324e-09, 1.17669809757545e-09 } }, - { { 8, 4, 8, 3 }, { 1.55179369321789e-02, -3.29310396921256e-02 } }, - { { 8, 6, 2, 3 }, { 3.68581034345984e-03, 1.16392983008537e-03 } }, - { { 2, 6, 6, 3 }, { -1.64913548260651e-09, 1.70894051570111e-10 } }, - { { 4, 6, 6, 3 }, { 2.77775993160253e-04, 3.77410302057860e-03 } }, - { { 2, 6, 8, 3 }, { 5.50878617883651e-02, -1.99531994223260e-03 } }, - { { 4, 6, 8, 3 }, { -4.67622885738260e-09, -6.98952053415614e-10 } }, - { { 2, 8, 8, 3 }, { 2.90052566099105e-09, 2.04564330047190e-09 } }, - { { 4, 8, 8, 3 }, { 1.78597171648502e-02, 3.17220781897178e-02 } }, - { { 6, 2, 4, 5 }, { 1.76420137232554e-09, 1.05104055437868e-10 } }, - { { 8, 2, 4, 5 }, { -3.02246152287104e-03, -9.54454245082383e-04 } }, - { { 4, 2, 8, 5 }, { 1.07924356530296e-02, -1.68834184202895e-03 } }, - { { 6, 4, 2, 5 }, { -7.84227887895553e-10, -8.65456802951857e-10 } }, - { { 8, 4, 4, 5 }, { 7.35799852084301e-10, -8.96392999068158e-10 } }, - { { 2, 6, 4, 5 }, { 1.64913548384803e-09, -1.70894048276102e-10 } }, - { { 4, 6, 4, 5 }, { -2.77775993160253e-04, -3.77410302057860e-03 } }, - { { 8, 6, 8, 5 }, { 2.10829501478453e-03, -9.24701177434334e-03 } }, - { { 2, 8, 2, 5 }, { 2.64933414192676e-08, -2.03285723876681e-08 } }, - { { 6, 2, 2, 7 }, { -3.44264963006675e-09, 9.90112058323764e-12 } }, - { { 8, 2, 2, 7 }, { -1.66776801001724e-03, 7.31485409650012e-03 } }, - { { 6, 2, 4, 7 }, { -5.50878617767860e-02, 1.99532026191665e-03 } }, - { { 8, 2, 4, 7 }, { -2.71542765860322e-09, 1.76543337688875e-09 } }, - { { 4, 2, 6, 7 }, { -1.07924356530296e-02, 1.68834184202895e-03 } }, - { { 8, 4, 2, 7 }, { -8.11616426817687e-10, 1.67305273280271e-09 } }, - { { 6, 4, 4, 7 }, { 4.05111131184309e-09, -1.17669809730382e-09 } }, - { { 8, 4, 4, 7 }, { -1.55179369321789e-02, 3.29310396921256e-02 } }, - { { 2, 6, 2, 7 }, { -4.07154503617311e-09, 3.34683197652399e-10 } }, - { { 4, 6, 2, 7 }, { -8.85008772454983e-03, 1.38448609718686e-03 } }, - { { 2, 6, 4, 7 }, { -5.50878617883651e-02, 1.99531994223259e-03 } }, - { { 4, 6, 4, 7 }, { 4.67622885713219e-09, 6.98952053111356e-10 } }, - { { 8, 6, 6, 7 }, { -2.10829501478453e-03, 9.24701177434335e-03 } }, - { { 4, 8, 2, 7 }, { -1.49528281786713e-09, -1.95530142297282e-09 } }, - { { 2, 8, 4, 7 }, { -2.90052566130477e-09, -2.04564330064451e-09 } }, - { { 4, 8, 4, 7 }, { -1.78597171648502e-02, -3.17220781897178e-02 } }, - { { 2, 2, 2, 2 }, { 2.61972936056406e-01, -4.66849721298391e-17 } }, - { { 4, 2, 2, 2 }, { 1.26743997186442e-09, -9.20430828601083e-12 } }, - { { 2, 2, 4, 2 }, { 1.26743997186442e-09, -9.20430828601083e-12 } }, - { { 6, 2, 6, 2 }, { 7.34497110698912e-02, -4.26240851124491e-10 } }, - { { 8, 2, 6, 2 }, { 4.01669748482391e-09, -3.60591433307660e-09 } }, - { { 6, 2, 8, 2 }, { 4.01669748482391e-09, -3.60591433307660e-09 } }, - { { 2, 4, 2, 2 }, { 1.26743996462707e-09, 9.20431322108966e-12 } }, - { { 4, 4, 2, 2 }, { 2.61943485031872e-01, -4.89004634963355e-18 } }, - { { 2, 4, 4, 2 }, { 2.00381403996136e-02, -1.40946282423116e-18 } }, - { { 4, 4, 4, 2 }, { -1.27168924172567e-09, 9.73022873840840e-12 } }, - { { 6, 4, 6, 2 }, { -5.63030148934130e-09, 1.78997963271364e-09 } }, - { { 8, 4, 6, 2 }, { 2.22515327441311e-02, -4.31016204922364e-02 } }, - { { 6, 4, 8, 2 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 8, 4, 8, 2 }, { -4.28392086824487e-10, -3.43537540206739e-09 } }, - { { 6, 6, 2, 2 }, { 2.50873194689164e-01, 4.69906880131097e-18 } }, - { { 2, 6, 6, 2 }, { 7.34497110698912e-02, 9.76529576584216e-18 } }, - { { 4, 6, 6, 2 }, { -4.51615804141971e-09, -1.41887388113540e-09 } }, - { { 2, 6, 8, 2 }, { 3.38241175346073e-09, -2.85419828918138e-09 } }, - { { 8, 8, 2, 2 }, { 2.50828949907785e-01, -3.88899237389951e-18 } }, - { { 6, 8, 4, 2 }, { 5.62113152593797e-03, 1.41002713662608e-02 } }, - { { 2, 8, 6, 2 }, { 3.38241175231252e-09, 2.85419826357845e-09 } }, - { { 4, 8, 6, 2 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, - { { 2, 8, 8, 2 }, { 1.04255386413001e-02, 5.42101086242752e-20 } }, - { { 4, 8, 8, 2 }, { 2.15553000799339e-09, 1.31756361460964e-09 } }, - { { 2, 2, 2, 4 }, { 1.26743996462707e-09, 9.20431322108966e-12 } }, - { { 4, 2, 2, 4 }, { 2.00381403996136e-02, -1.40946282423116e-18 } }, - { { 2, 2, 4, 4 }, { 2.61943485031872e-01, -4.89004634963355e-18 } }, - { { 4, 2, 4, 4 }, { -1.27168924172567e-09, 9.73022873840840e-12 } }, - { { 6, 2, 6, 4 }, { -5.63030148934130e-09, 1.78997963271364e-09 } }, - { { 8, 2, 6, 4 }, { 4.60947946335450e-03, -1.15626037854253e-02 } }, - { { 6, 2, 8, 4 }, { 2.22515327441311e-02, -4.31016204922364e-02 } }, - { { 8, 2, 8, 4 }, { -4.28392086824487e-10, -3.43537540206739e-09 } }, - { { 4, 4, 2, 4 }, { -1.27168924980376e-09, -9.73022414045207e-12 } }, - { { 2, 4, 4, 4 }, { -1.27168924980376e-09, -9.73022414045207e-12 } }, - { { 4, 4, 4, 4 }, { 2.61914049687002e-01, 3.68803411812837e-17 } }, - { { 8, 4, 6, 4 }, { -1.11475987348867e-09, 4.36237058648892e-09 } }, - { { 6, 4, 8, 4 }, { -1.11475987348867e-09, 4.36237058648892e-09 } }, - { { 8, 4, 8, 4 }, { -1.85517291206674e-02, -2.61152081623646e-02 } }, - { { 8, 6, 2, 4 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 6, 6, 4, 4 }, { 2.50843627819692e-01, 2.68188203881229e-17 } }, - { { 2, 6, 6, 4 }, { -4.51615803043331e-09, 1.41887386867267e-09 } }, - { { 4, 6, 6, 4 }, { 1.48617254260414e-02, -2.16840434497101e-18 } }, - { { 2, 6, 8, 4 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 4, 6, 8, 4 }, { -2.00828745421621e-09, 2.74866711044360e-09 } }, - { { 8, 8, 4, 4 }, { 2.50799402750969e-01, 1.82057755524117e-17 } }, - { { 4, 8, 6, 4 }, { -2.00828744417945e-09, -2.74866710693906e-09 } }, - { { 2, 8, 8, 4 }, { 2.15552999177470e-09, -1.31756362202660e-09 } }, - { { 4, 8, 8, 4 }, { 3.20339000240785e-02, -1.73472347597681e-18 } }, - { { 6, 2, 2, 6 }, { 7.34497110698912e-02, 9.76529576584216e-18 } }, - { { 8, 2, 2, 6 }, { 3.38241175346073e-09, -2.85419828918138e-09 } }, - { { 6, 2, 4, 6 }, { -4.51615804141971e-09, -1.41887388113540e-09 } }, - { { 2, 2, 6, 6 }, { 2.50873194689164e-01, 4.69906880131097e-18 } }, - { { 6, 4, 2, 6 }, { -4.51615803043331e-09, 1.41887386867267e-09 } }, - { { 8, 4, 2, 6 }, { 2.22515329942571e-02, -4.31016203631071e-02 } }, - { { 6, 4, 4, 6 }, { 1.48617254260414e-02, -2.16840434497101e-18 } }, - { { 8, 4, 4, 6 }, { -2.00828745421621e-09, 2.74866711044360e-09 } }, - { { 4, 4, 6, 6 }, { 2.50843627819692e-01, 2.68188203881229e-17 } }, - { { 2, 4, 8, 6 }, { 5.62113152593796e-03, -1.41002713662608e-02 } }, - { { 2, 6, 2, 6 }, { 7.34497110698911e-02, 4.26240870655083e-10 } }, - { { 4, 6, 2, 6 }, { -5.63030150095342e-09, -1.78997964451953e-09 } }, - { { 2, 6, 4, 6 }, { -5.63030150095342e-09, -1.78997964451953e-09 } }, - { { 6, 6, 6, 6 }, { 2.46623945475382e-01, -9.66681842914379e-18 } }, - { { 2, 8, 2, 6 }, { 4.01669748399264e-09, 3.60591430678317e-09 } }, - { { 4, 8, 2, 6 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, - { { 2, 8, 4, 6 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 4, 8, 4, 6 }, { -1.11475986935356e-09, -4.36237059612427e-09 } }, - { { 8, 8, 6, 6 }, { 2.46582791504814e-01, 6.82292257170944e-19 } }, - { { 6, 8, 8, 6 }, { 1.31792902727351e-02, -1.24683249835833e-18 } }, - { { 6, 2, 2, 8 }, { 3.38241175231252e-09, 2.85419826357845e-09 } }, - { { 8, 2, 2, 8 }, { 1.04255386413001e-02, 5.42101086242752e-20 } }, - { { 6, 2, 4, 8 }, { 2.22515329942571e-02, 4.31016203631071e-02 } }, - { { 8, 2, 4, 8 }, { 2.15553000799339e-09, 1.31756361460964e-09 } }, - { { 4, 2, 6, 8 }, { 5.62113152593797e-03, 1.41002713662608e-02 } }, - { { 2, 2, 8, 8 }, { 2.50828949907785e-01, -3.88899237389951e-18 } }, - { { 8, 4, 2, 8 }, { 2.15552999177470e-09, -1.31756362202660e-09 } }, - { { 6, 4, 4, 8 }, { -2.00828744417945e-09, -2.74866710693906e-09 } }, - { { 8, 4, 4, 8 }, { 3.20339000240785e-02, -1.73472347597681e-18 } }, - { { 4, 4, 8, 8 }, { 2.50799402750969e-01, 1.82057755524117e-17 } }, - { { 2, 6, 2, 8 }, { 4.01669748399264e-09, 3.60591430678317e-09 } }, - { { 4, 6, 2, 8 }, { 4.60947946335450e-03, 1.15626037854253e-02 } }, - { { 2, 6, 4, 8 }, { 2.22515327441311e-02, 4.31016204922363e-02 } }, - { { 4, 6, 4, 8 }, { -1.11475986935356e-09, -4.36237059612427e-09 } }, - { { 8, 6, 6, 8 }, { 1.31792902727351e-02, -1.24683249835833e-18 } }, - { { 6, 6, 8, 8 }, { 2.46582791504814e-01, 6.82292257170944e-19 } }, - { { 4, 8, 2, 8 }, { -4.28392072459286e-10, 3.43537539337673e-09 } }, - { { 2, 8, 4, 8 }, { -4.28392072459286e-10, 3.43537539337673e-09 } }, - { { 4, 8, 4, 8 }, { -1.85517291206674e-02, 2.61152081623646e-02 } }, - { { 8, 8, 8, 8 }, { 2.46541664704192e-01, 1.10215294407731e-17 } }, - { { 1, 1, 0, 0 }, { -2.11636226073930e+00, 1.02763625347668e-18 } }, - { { 5, 1, 0, 0 }, { 1.19046590368770e-09, -5.57499617699363e-12 } }, - { { 3, 3, 0, 0 }, { -2.11591498795759e+00, 8.09942036238525e-17 } }, - { { 5, 5, 0, 0 }, { -1.68636099808535e+00, 7.71371067496320e-18 } }, - { { 7, 7, 0, 0 }, { -1.68576161450246e+00, 3.76062776246208e-18 } }, - { { 2, 2, 0, 0 }, { -2.11636226073930e+00, 5.03521382473279e-19 } }, - { { 6, 2, 0, 0 }, { 1.19046603507266e-09, 5.57499896179912e-12 } }, - { { 4, 4, 0, 0 }, { -2.11591498795759e+00, 1.35457336871340e-16 } }, - { { 6, 6, 0, 0 }, { -1.68636099808535e+00, -8.60733043431649e-18 } }, - { { 8, 8, 0, 0 }, { -1.68576161450246e+00, -9.10040816524792e-17 } }, - { { 0, 0, 0, 0 }, { -1.02932237633033e+02, 0.00000000000000e+00 } } - }; - - // Uncomment below to test the align function - // TODO: This should be tested in a better manner! - // maquis::integral_map integrals2; - - // for (auto&& it : integrals) - // integrals2[it->first] = it->second; - - p.set("integrals_binary", maquis::serialize(integrals)); - p.set("site_types", "1,1,1,1,1,1,1,1"); - p.set("L", 8); - p.set("irrep", 1); - - p.set("nsweeps",10); - p.set("max_bond_dimension",512); - - p.set("nelec", 3); - - maquis::prepare_relativistic(p); - - // Measure 1-RDM - p.set("MEASURE[1rdm]","1"); - p.set("MEASURE[2rdm]","1"); - - maquis::DMRGInterface interface(p); - +#ifdef HAVE_U1DG + maquis::DMRGInterface> interface(parametersComplex); interface.optimize(); - - // check energy + // Checks energy BOOST_CHECK_CLOSE(std::real(interface.energy()), -1.0780470133e+02 , 1e-7); - - - const typename maquis::DMRGInterface::meas_with_results_type& meas = interface.onerdm(); - - // we don't have a map for the measurements yet, so we'll do it the stupid way - + const typename maquis::DMRGInterface>::meas_with_results_type& meas = interface.onerdm(); // Calculate the trace of the 1-RDM and check if it adds up to the number of electrons - Complex value = 0.0; - + std::complex value = 0.0; for (int i = 0; i < meas.first.size(); i++) if (meas.first[i][0] == meas.first[i][1]) // sum up diagonal elements for the trace value += meas.second[i]; - BOOST_CHECK_CLOSE(value.real(), 3.0 , 1e-7); - - - #endif +#endif } -