Skip to content

feat: add pick command for reduce#429

Open
henryiii wants to merge 2 commits into
boostorg:developfrom
henryiii:pick-reduce
Open

feat: add pick command for reduce#429
henryiii wants to merge 2 commits into
boostorg:developfrom
henryiii:pick-reduce

Conversation

@henryiii

@henryiii henryiii commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

This is a potential implementation of a pick command.

This is a test run of Claude Fable 5, which was released today.

🤖 AI text below 🤖

Closes #275.

This adds a pick command to algorithm::reduce, which selects an arbitrary subset of bins by index from an axis which is not ordered, like the category axis.

auto h = make_histogram(axis::category<std::string>({"red", "green", "blue"}));
// ...
auto h2 = algorithm::reduce(h, pick({2, 0})); // axis is now {"blue", "red"}

Design

  • pick(iaxis, indices) / pick(indices) follow the same positional/explicit-index convention as the other reduce commands. Indices must be unique and non-empty (std::invalid_argument otherwise); out-of-range indices are rejected inside reduce.
  • Unlike slice, the picked bins do not have to be adjacent, and the order of the indices determines the bin order of the new axis, so pick can also reorder an unordered axis.
  • Counts in bins which are not picked are added to the overflow bin if present, otherwise discarded — consistent with how slice already treats unordered axes.
  • pick cannot be fused with any other command for the same axis.
  • As suggested in Add pick command for reduce #275, this introduces a new kind of reduce constructor: A(const A& src, const std::vector<index_type>& indices). A new public trait axis::traits::is_pickable detects it, mirroring is_reducible, so user-defined axes can opt in. axis::category implements it; ordered axes (regular, variable, integer, circular) throw, since picking a non-adjacent subset from them would require changing the axis type, which reduce does not support yet (see discussion in Add pick command for reduce #275 about a future discontinuous axis / type-changing reduce).

Testing

  • New tests in algorithm_reduce_test.cpp: pick with/without overflow bin, reordering, 2d correlation preservation, static and dynamic histograms (through axis::variant), the iterable overload, and all error paths (empty, duplicate, out-of-range indices, non-pickable axis, fusion conflicts). New code paths are fully exercised for the coverage gate.
  • is_pickable true/false cases in axis_traits_test.cpp.
  • Docs: changelog, guide reduction section, Axis concept (new special constructor), and a runnable example in guide_histogram_reduction.cpp.

🤖 Generated with Claude Code

henryiii added 2 commits June 9, 2026 16:59
Add a pick command to algorithm::reduce, which selects an arbitrary
subset of bins by index from an axis which is not ordered, like the
category axis. Unlike slice, the picked bins do not have to be
adjacent, and they may be given in any order, which reorders the bins
in the new axis. Counts in bins which are not picked are added to the
overflow bin, if it is present, consistent with how slice treats
unordered axes; otherwise they are discarded.

Axes opt into picking with a new special constructor which accepts the
original axis and a vector of bin indices to keep. The new trait
axis::traits::is_pickable detects this constructor, mirroring
is_reducible. axis::category implements it; ordered axes throw
invalid_argument, since picking a non-adjacent subset from them would
require changing the axis type, which reduce does not support yet.

Fixes boostorg#275

Assisted-by: ClaudeCode:claude-fable-5
Windows CI failed two ways:
- C1128 (too many sections) when compiling algorithm_reduce_test.cpp;
  add /bigobj for the test under CMake, matching the b2 build which
  already sets it globally and the existing fill/operators tests.
- C4702 (unreachable code, treated as error) for the non-pickable
  static_if branch in reduce(). Unlike is_reducible (true for all
  standard axes), is_pickable is false for most axes, so that branch is
  codegen'd and MSVC flags the value after the noreturn throw. Guard the
  function with a 4702 pragma, mirroring detail/fill.hpp.

Assisted-by: ClaudeCode:claude-opus-4.8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add pick command for reduce

1 participant