.. _program_listing_file_SeQuant_domain_mbpt_rules_csv.cpp: Program Listing for File csv.cpp ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``SeQuant/domain/mbpt/rules/csv.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Created by Eduard Valeyev on 3/8/25. // #include #include #include #include #include namespace sequant::mbpt { ExprPtr csv_transform_impl(Tensor const& tnsr, const IndexSpace& csv_basis, std::wstring_view coeff_tensor_label) { using ranges::views::transform; if (ranges::none_of(tnsr.const_braket_indices(), &Index::has_proto_indices)) return nullptr; SEQUANT_ASSERT(ranges::none_of(tnsr.aux(), &Index::has_proto_indices)); SEQUANT_ASSERT(get_default_context().index_space_registry()); SEQUANT_ASSERT( get_default_context().index_space_registry()->contains(csv_basis)); // shortcut for the CSV overlap if csv_basis is orthonormal (assume LCAO bases // are orthonormal!) const bool csv_basis_is_ao = bitset_t(csv_basis.qns()) & bitset_t(LCAOQNS::ao); const bool csv_basis_is_pao = bitset_t(csv_basis.qns()) & bitset_t(LCAOQNS::pao); const bool csv_basis_is_orthonormal = !(csv_basis_is_ao || csv_basis_is_pao); if (csv_basis_is_orthonormal && tnsr.label() == overlap_label()) { SEQUANT_ASSERT(tnsr.bra_rank() == 1 // && tnsr.ket_rank() == 1 // && tnsr.aux_rank() == 0); auto&& bra_idx = tnsr.bra().at(0); auto&& ket_idx = tnsr.ket().at(0); [[maybe_unused]] const auto bra_has_proto_indices = bra_idx.has_proto_indices(); [[maybe_unused]] const auto ket_has_proto_indices = ket_idx.has_proto_indices(); SEQUANT_ASSERT(bra_has_proto_indices || ket_has_proto_indices); if (bra_has_proto_indices && ket_has_proto_indices) { auto dummy_idx = ordinal_compare(bra_idx, ket_idx) // ? bra_idx.drop_proto_indices() // : ket_idx.drop_proto_indices(); return ex( 1, ExprPtrList{ex(coeff_tensor_label, // bra({bra_idx}), ket({dummy_idx})), // ex(coeff_tensor_label, // bra({dummy_idx}), ket({ket_idx}))}); } else { return ex( 1, ExprPtrList{ex(coeff_tensor_label, // bra({bra_idx}), ket({ket_idx}))}); } } Product result; container::svector rbra, rket; rbra.reserve(tnsr.bra_rank()); for (auto&& idx : tnsr.bra()) { if (idx.has_proto_indices()) { Index xidx = Index::make_tmp_index(csv_basis); result.append( 1, ex(coeff_tensor_label, bra({idx}), ket({xidx}), aux({}))); rbra.emplace_back(std::move(xidx)); } else rbra.emplace_back(idx); } rket.reserve(tnsr.ket_rank()); for (auto&& idx : tnsr.ket()) { if (idx.has_proto_indices()) { Index xidx = Index::make_tmp_index(csv_basis); result.append( 1, ex(coeff_tensor_label, bra({xidx}), ket({idx}), aux({}))); rket.emplace_back(std::move(xidx)); } else rket.emplace_back(idx); } auto xtnsr = ex(tnsr.label(), bra(rbra), ket(rket), tnsr.aux(), tnsr.symmetry(), tnsr.braket_symmetry(), tnsr.column_symmetry()); result.prepend(1, std::move(xtnsr)); return ex(std::move(result)); } ExprPtr csv_transform(ExprPtr const& expr, const IndexSpace& csv_basis, std::wstring const& coeff_tensor_label, container::svector const& tensor_labels) { using ranges::views::transform; if (expr->is()) return ex(*expr // | transform([&csv_basis, &coeff_tensor_label, // &tensor_labels](auto&& x) { return csv_transform(x, csv_basis, coeff_tensor_label, tensor_labels); })); else if (expr->is()) { auto const& tnsr = expr->as(); if (!ranges::contains(tensor_labels, tnsr.label())) return expr; if (ranges::none_of(tnsr.indices(), &Index::has_proto_indices)) return expr; return csv_transform_impl(tnsr, csv_basis, coeff_tensor_label); } else if (expr->is()) { auto const& prod = expr->as(); Product result; result.scale(prod.scalar()); for (auto&& f : prod.factors()) { auto trans = csv_transform(f, csv_basis, coeff_tensor_label, tensor_labels); // N.B. do not flatten the product to ensure that CSV transform of // each factor is performed before assembling the final product // this way for DF-factorized integrals each DF factor is transformed // to CSV basis before DF reconstruction result.append(1, trans ? trans : f, Product::Flatten::No); } return ex(std::move(result)); } else return expr; } } // namespace sequant::mbpt