Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sparse indices for diff_tensors() #360

Merged
merged 14 commits into from
Nov 12, 2023
3 changes: 2 additions & 1 deletion doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Changes

- Substantial speedups in the computation of first-order derivatives
with respect to many variables/parameters
(`#358 <https://github.com/bluescarni/heyoka/pull/358>`__).
(`#360 <https://github.com/bluescarni/heyoka/pull/360>`__,
`#358 <https://github.com/bluescarni/heyoka/pull/358>`__).
- Substantial performance improvements in the computation of
derivative tensors of large expressions with a high degree
of internal redundancy
Expand Down
28 changes: 21 additions & 7 deletions include/heyoka/expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,21 +419,30 @@ IGOR_MAKE_NAMED_ARGUMENT(diff_order);
namespace detail
{

// Private aliases/utilities needed in the implementation of dtens.
using dtens_v_idx_t = std::vector<std::uint32_t>;

struct dtens_v_idx_cmp {
[[nodiscard]] bool operator()(const dtens_v_idx_t &, const dtens_v_idx_t &) const;
// Sparse structure used to index derivatives in dtens:
// - the first element of the pair is the function component index,
// - the second element is the vector of variable index/diff order pairs,
// which is kept sorted according to the variable index, and in which no
// diff order can be zero and no variable index can appear twice.
using dtens_sv_idx_t = std::pair<std::uint32_t, std::vector<std::pair<std::uint32_t, std::uint32_t>>>;

struct dtens_sv_idx_cmp {
[[nodiscard]] bool operator()(const dtens_sv_idx_t &, const dtens_sv_idx_t &) const;
};

using dtens_map_t = boost::container::flat_map<dtens_v_idx_t, expression, dtens_v_idx_cmp>;
using dtens_map_t = boost::container::flat_map<dtens_sv_idx_t, expression, dtens_sv_idx_cmp>;

} // namespace detail

class HEYOKA_DLL_PUBLIC dtens
{
public:
using v_idx_t = detail::dtens_v_idx_t;
// Derivative indexing vector in dense form.
using v_idx_t = std::vector<std::uint32_t>;

// Derivative indexing vector in sparse form.
using sv_idx_t = detail::dtens_sv_idx_t;

using size_type = detail::dtens_map_t::size_type;

private:
Expand Down Expand Up @@ -509,6 +518,11 @@ HEYOKA_DLL_PUBLIC std::ostream &operator<<(std::ostream &, const dtens &);

HEYOKA_END_NAMESPACE

// Version changelog:
// - version 1: switched from dense to sparse
// format for the indices vectors.
BOOST_CLASS_VERSION(heyoka::dtens::impl, 1)

// fmt formatter for dtens, implemented
// on top of the streaming operator.
namespace fmt
Expand Down
Loading