Skip to content

Releases: HighDiceRoller/icepool

v2.2.1

27 Dec 00:43

Choose a tag to compare

v2.2.1 - 25 December 2025

  • Added wild, wild_low, and wild_high options to largest_count() evaluation. These allow specifying outcomes as wild, combining with any outcomes, outcomes that they are lower than, and outcomes that they are higher than respectively.
  • standard_pool renamed to d_pool, leaving a deprecation warning.

v2.2.0

12 Dec 01:45

Choose a tag to compare

v2.2.0 - 11 December 2025

Major modifications to map(repeat) Markov process flow.

  • Now requires Python >= 3.12 (from 3.10).
  • Reroll split into separate Reroll and Restart symbols with different meanings in map(repeat) and Again.
    • In map(repeat), Reroll rerolls only the current stage, while Restart restarts the entire process.
    • With again_count, Reroll rerolls any dice over the limit until they don't roll Again, while Restart restarts the entire process.
    • With again_depth, Reroll rerolls the last depth if going over the limit, while Restart cannot be used with again_depth.
  • Break outcome wrapper that can be returned from a function sent to map(repeat) in order to immediately terminate the Markov process.
  • map(repeat) now defaults to repeat=None; repeat is now explicitly incompatible with Again.
  • Remove separate time_limit parameter to map(); repeat now always returns early if fully absorbed.
  • again_end can now be used with again_count.
  • .weightless() method for multiset generators that sets the quantity for all possible multisets to 1.
  • New product_of_counts() multiset evaluation.
  • More specific overloads for map, tupleize, vectorize.
  • Rename commonize_denominator() to harmonize_denominator() and add optional weight parameter.
  • Fix immediate absorption case for map(repeat='inf').

v2.1.2

08 Aug 02:44

Choose a tag to compare

v2.1.2 - 7 August 2025

  • Breaking change: difference (but not other operations) now has keep_negative_counts parameter again, which defaults to False.

v2.1.1 - 4 August 2025

  • Experimental sort_pair_keep_while() and sort_pair_drop_while() multiset ops.

v2.1.0

30 Jul 05:07

Choose a tag to compare

v2.1.0 - 30 July 2025

  • Breaking change: any() multiset evaluation renamed and inverted to empty().
  • Breaking change: sort_match() renamed to sort_pair(), maximum_match_highest() renamed to max_pair_highest() and similar for minimum_match_highest().
  • Add extra parameter to sort_pair.
  • Rename several which and target parameters to outcomes.
  • Make max_rerolls and depth parameters of reroll_to_pool() keyword-only, and add default outcomes to reroll.
  • Experimental leximin() and leximax() multiset evaluations.
  • Experimental versus_any() and versus_all() multiset operations.

v2.0.2

19 May 01:44

Choose a tag to compare

v2.0.2 - 1 April 2025

  • Fix default next_state_key identification.

v2.0.1 - 1 April 2025

  • Adjusted behavior of MultisetEvaluator caching between calls to evaluate() depending on the value of next_state_key.
    • By default, next_state_key will only cache if the evaluator is called directly (i.e. not inside a @multiset_function).
    • If a full next_state_key is given, it will cache inside @multiset_function, provided the other contents agree.
    • The special value NoCache will disable caching.
  • Support argumentless evaluations.
  • Some typing fixes.

v2.0.0

31 Mar 04:14

Choose a tag to compare

v2.0.0 - 31 March 2025

Major rewrite of multiset handling. Things will be more unstable than usual for a while.

  • MultisetEvaluator.next_state() now has an explicit parameter with the order in which outcomes are seen.
  • Optional MultisetEvaluator.initial_state() method.
  • MultisetEvaluator.initial_state() and final_state() now get the following parameters:
    • The order in which outcomes are / were seen.
    • All outcomes that will be / were seen.
    • The sizes of the input multisets, if inferrable with counts being non-negative.
    • Non-multiset keyword arguments that were passed to evaluate().
  • ascending and descending variants of next_state no longer exist.
    • Instead, raise UnsupportedOrder() if you don't like the current order. The other order will automatically be tried.
    • This can be done in initial_state() (recommended), next_state(), or final_outcome().
  • Multiset operator order is now always attached to the evaluator side rather than the generator side.
    • Unless the operator modifies the generator in-place, but in this case both orders will certainly be supported.
  • MultisetEvaluator can optionally provide a key for persistent caching.
  • Some existing expressions and evaluators now take advantage of inferred multiset sizes.
    • In particular, keep() and sorted_match().
  • MultisetExpression.count() renamed to size().
  • @multiset_function now implements late binding like a standard Python method. (Though I still recommend using only pure functions.)
  • @multiset_function now accepts variadic arguments.
  • @multiset_function now accepts non-multiset keyword arguments.
  • @multiset_function now works with joint evaluations where some sub-evaluations don't contain parameters.
  • Hopefully better @multiset_function performance.
  • Alignment class is retired.
  • Deprecated depth=None is removed from Die.reroll().
  • Multiset generators now always produce a single count value, with MultiDeal now producing tuple-valued counts rather than taking up multiple argument slots.
  • Multiset computations now try to infer multiset sizes if the counts are non-negative. This improves the applicability of keep and sort_match expressions.
  • Cartesian products (e.g. tupleize) now return Reroll if any argument is Reroll.

v1.7.2

26 Feb 06:21

Choose a tag to compare

This is likely the end of the v1.x series apart from bugfixes.

v1.7.2 - 25 February 2025

  • Add Population.append() and .remove() methods.
  • Improve Vector performance.
  • Adjusted typing of mixture expressions.
  • Experimental Wallenius noncentral hypergeometric.

v1.7.1

11 Feb 06:08

Choose a tag to compare

v1.7.1 - 10 February 2025

  • Fix joint evaluations and @multiset_function interaction with next_state_ascending and next_state_descending.

v1.7.0 - 9 February 2025

  • Overhauled multiset expressions. This allows expressions that are given to an evaluator to have the evaluation persistently cached. This makes the caching behavior more consistent: a single expression will be cached in the final evaluator (e.g. (a - b).unique().sum() would be cached in the sum evaluator), and @multiset_function creates an evaluator like any other. Unfortunately, this did come at some performance cost for @multiset_function. I have some ideas on how to claw back some of the performance but I haven't decided whether it's worth the complexity.
  • Instead of specifying order() for an evaluator, you can now implement next_state_ascending() and/or next_state_descending().
  • Alignment now has a denominator of 1.
  • keep(), isdisjoint(), sort_match(), and maximum_match() operations now treat negative incoming counts as zero rather than raising an error.
  • Add Population.group_by() method to split a population into a "covering" set of conditional probabilities.
    • Population.group_by[] can also be used to group by index or slice.
  • Move split() from Die to the base Population class.
  • Straight-related multiset operations can now choose between prioritizing low and high outcomes.
  • Store original names of @multiset_function parameters.

v1.6.1

18 Nov 01:48

Choose a tag to compare

v1.6.1 - 17 November 2024

  • Add pointwise_max, pointwise_min arguments to take pointwise maximum or minimum of CDFs.
  • Add Die.time_to_sum() method.
  • Fix identification of absorbing states in the presence of extra_args in map_and_time().
  • Add time_limit parameter to map().
  • repeat parameter now uses 'inf' to request the absorbing distribution rather than None.

v1.6.0

21 Sep 16:41

Choose a tag to compare

v1.6.0 - 20 September 2024

  • Breaking change: outcomes with zero quantities are removed when constructing Die and Deck.
    • Functions and methods relating to zero-quantities are removed: align(), align_range(), Population.has_zero_quantities(), Die.trim(), Die.set_range(), Die.set_outcomes().
    • You can use consecutive() or sorted_union() to get an appropriate superset of sets of outcomes.
  • Breaking change: MultisetEvaluator.alignment() is renamed to MultisetEvaluator.extra_outcomes().
    • MultisetEvaluator.range_alignment() is renamed to MultisetEvaluator.consecutive().
    • The Alignment class is no longer public.
  • Breaking change: Deck.multiply_counts() and Population.scale_quantities() are replaced/renamed to Population.multiply_quantities() etc.
  • Add Deck.sequence() and Die.sequence() method.
  • Add Population.pad_to_denominator() method.
  • Move zero() and zero_outcome() from Die to Population.
  • @ operator now sums left-to-right.
  • Remove old compair evaluation.
  • min_outcome() and max_outcome() free functions can now be called using a single iterable argument.
  • Forward algorithm now has a persistent cache.
  • Add skip optimization for single deals with keep tuples.
  • Pools now only skip dice, not outcomes. This is a bit slower in some cases but provides more consistent iteration order.
  • Add shared evaluator instances for some built-in evaluator for caching.
  • Simplify determination of outcome order for multiset evaluations.
  • Simplify implementation of generator unbinding.
  • Fix extra_args expansion for map_and_time.