From ef8e031f014ec470bafa5635594176a79d1e5011 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 10 Nov 2023 22:08:34 +0100 Subject: [PATCH] Several fixes, provisional WIP. --- src/expression_diff.cpp | 40 ++++++++++++++++++++++++-------- test/expression_diff_tensors.cpp | 4 ++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/expression_diff.cpp b/src/expression_diff.cpp index cc967743d..8c95ddc9f 100644 --- a/src/expression_diff.cpp +++ b/src/expression_diff.cpp @@ -1236,7 +1236,9 @@ auto diff_tensors_impl(const std::vector &v_ex, const std::vectorfirst.second.empty()); - return (end() - 1)->first.second.back().second; + const auto &sv = (end() - 1)->first.second; + if (sv.empty()) { + return 0; + } else { + return sv.back().second; + } } dtens::iterator dtens::find(const v_idx_t &vidx) const @@ -1493,6 +1499,12 @@ dtens::iterator dtens::find(const v_idx_t &vidx) const return end(); } + // The size of vidx must be consistent with the number + // of diff args. + if (vidx.size() - 1u != get_nvars()) { + return end(); + } + // Turn vidx into sparse format. detail::dtens_sv_idx_t s_vidx{vidx[0], {}}; for (decltype(vidx.size()) i = 1; i < vidx.size(); ++i) { @@ -1538,7 +1550,10 @@ dtens::subrange dtens::get_derivatives(std::uint32_t order) const // Create the indices vector corresponding to the first derivative // of component 0 for the given order in the map. - detail::dtens_sv_idx_t s_vidx{0, {{0, order}}}; + detail::dtens_sv_idx_t s_vidx{0, {}}; + if (order != 0u) { + s_vidx.second.emplace_back(0, order); + } // Locate the corresponding derivative in the map. // NOTE: this could be end() for invalid order. @@ -1560,8 +1575,10 @@ dtens::subrange dtens::get_derivatives(std::uint32_t order) const // map is empty, and we handled this corner case earlier. assert(get_nouts() > 0u); s_vidx.first = get_nouts() - 1u; - assert(get_nvars() > 0u); - s_vidx.second[0].first = get_nvars() - 1u; + if (order != 0u) { + assert(get_nvars() > 0u); + s_vidx.second[0].first = get_nvars() - 1u; + } // NOTE: this could be end() for invalid order. auto e = p_impl->m_map.find(s_vidx); @@ -1596,7 +1613,10 @@ dtens::subrange dtens::get_derivatives(std::uint32_t component, std::uint32_t or // Create the indices vector corresponding to the first derivative // for the given order and component in the map. - detail::dtens_sv_idx_t s_vidx{component, {{0, order}}}; + detail::dtens_sv_idx_t s_vidx{component, {}}; + if (order != 0u) { + s_vidx.second.emplace_back(0, order); + } // Locate the corresponding derivative in the map. // NOTE: this could be end() for invalid component/order. @@ -1615,7 +1635,9 @@ dtens::subrange dtens::get_derivatives(std::uint32_t component, std::uint32_t or // Modify vidx so that it now refers to the last derivative // for the given order and component in the map. assert(get_nvars() > 0u); - s_vidx.second[0].first = get_nvars() - 1u; + if (order != 0u) { + s_vidx.second[0].first = get_nvars() - 1u; + } // NOTE: this could be end() for invalid component/order. auto e = p_impl->m_map.find(s_vidx); @@ -1692,8 +1714,6 @@ std::uint32_t dtens::get_nvars() const if (p_impl->m_map.empty()) { assert(ret == 0u); - } else { - assert(!begin()->first.second.empty()); } #endif diff --git a/test/expression_diff_tensors.cpp b/test/expression_diff_tensors.cpp index aa04923c4..05fcc4a13 100644 --- a/test/expression_diff_tensors.cpp +++ b/test/expression_diff_tensors.cpp @@ -384,6 +384,8 @@ TEST_CASE("dtens basics") REQUIRE(dt3.get_args() == dt2.get_args()); } +#if 0 + TEST_CASE("fixed centres check") { std::uniform_real_distribution rdist(-10., 10.); @@ -577,6 +579,8 @@ TEST_CASE("speelpenning check") } } +#endif + TEST_CASE("speelpenning complexity") { fmt::print("Speelpenning's example\n");