Repository navigation
Release 0.13 - #261
Merged
Merged
Release 0.13#261
Conversation
… guide (#260) * Refuse node_availability with crews and common-cause groups (#251) With limited repair crews, every long-run value but node_availability already refused common-cause groups. node_availability gave each component's value in the crews' chain, which has no common causes, although a shared failure leaves one member waiting for the crew. The crews' chain now refuses groups itself (_require_crew_chain), so neither it nor its route can be read without them. The refusal says to simulate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Keep every level's structure up to date; no truth tables (#255) The compiled engine built a table of whether the system works in each of the 2^n states of its components (n <= 20), and one for each nested RBD, on every run: 0.11 s for 20 components, over half of a 1,000-simulation run. The incremental structure it used above 20 components is as fast as the table at every size measured, and faster at 20, so it is now the one way: _compiled._kept lays out every level's structure as one (each path set's level, each level's root and whether it always works), and the kernel keeps it up to date at every level (_keep, _level_works). The tables, truth_table, _works and MAX_TABLED are gone, and with them the refusal of a nested RBD of more than 20 components. Results are the same, bit for bit. A 1,000-simulation run of two lines of ten components takes 0.036 s rather than 0.119 s; 20,000, 0.62 s rather than 0.70 s. engines.API is 3, as the run's arrays changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Work out each stream's key once a run (#254) A run's Plan keeps each stream's Philox key, worked out once, and hands it to the blocks: 40 SeedSequences rather than 800 for 20,000 simulations of 20 components (about 0.035 s of 0.65 s). Laying the draws out more tightly was measured and left out: a limit for each simulation, extended alone, with first chunks nearer the expected draws, worked out a third fewer values but ran the simulations that ran out again, for no net gain on any of five benchmarks. The quantile functions' overhead is raised in surpyval (SurPyval#769). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Capacity: add up equal levels with a sorted reduction (#246) merged() summed the probabilities of equal levels with np.add.at, one row at a time. A stable sort of the rows by level and np.add.reduceat make the same sums in the same order (each level from its first row, and 0.0 + x is x), so results are the same, bit for bit. tidy() is cached: a run tidies the same few levels for every state it meets. 25 redundant pairs in series (50 components with capacities), 2,000 h, numba: 500 simulations 0.39 s -> 0.31 s, 2,000 simulations 1.04 s -> 0.96 s; 70 pairs on the Python loop, 100 simulations, 3.83 s -> 3.5 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Timelines: work out each change's position once (#247) A _Data's changes' histories and positions in them are a cached property, worked out once with a repeat of the offsets (no gather through the histories' numbers), where every measure (uptime, failures, the curve, the merges) worked them out again. A unit's own histories no longer store their changes' index among their cause's changes, which is their position (index None; _Data.indices gives either). Results are the same, bit for bit. The 12-component bridge feeding a vote, 20,000 simulations, numba: simulate_timelines 0.76 s -> 0.69 s, the first measures over its result 0.79 s -> 0.68 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Conditional runs: order the modules' changes in one sort (#248) paths() put every module's changes in order with a four-key lexsort, and the stretches with another. The changes now take one sort of a key that grows with the simulation and the time (each simulation's times shifted past the one before's by a power of two beyond the window, so rounding never puts two out of order), and each run of equal keys (changes at one instant, or within rounding) is put in order exactly: by simulation, time, rank, then as given. The stretches need no sort: a simulation's start goes before its first change, the changes already in order. values() and capacity_values() find each joint state's stretches, and the changes down from and into it, from one stable sort, rather than comparing every stretch with every state. Results are the same, bit for bit. Also: the simulation guide said the compiled engine takes nested RBDs of up to 20 components, which #255 lifted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * CHANGELOG: faster capacity runs, timelines and conditional runs (#246, #247, #248) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Capacity: black (#246) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Capacity: sum no levels when none is given; equal to np.add.at to rounding (#246) The sorted reduction marked a first row even with no rows, so a run whose capacity had no level left failed in add.reduceat. Its sums also differ from np.add.at's in the last bits where a level has three or more rows (reduceat adds a level's later rows up before its first): the test now checks the sums to rounding and the levels exactly, and the CHANGELOG says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS * Release 0.13: remove what 0.12 deprecated; version, CHANGELOG, saving guide What 0.12 deprecated goes: calling SparesDemand.mean() or std(), properties since 0.12 (#184), raises TypeError, as do StandbyModel's and LoadSharingModel's mc_samples, lower and seed, which set a fit to simulated lifetimes that 0.12 removed (#149). StandbyModel's switching_probability and dormancy_factor came after them, so they are given by name, and a call that gave them by position is refused rather than misread. test_removed_in_0_13 keeps them gone. deprecation.NEXT_REMOVAL is now 0.14, what 0.13 deprecates (offsets=, CapacityDistribution.mean() called, an exact mean's simulation options), and REMOVAL_AFTER_NEXT goes. The CHANGELOG's [Unreleased] becomes [0.13] - 2026-10-09, with its summary and behaviour changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The 0.13 release: #260, from dev into master. #259 already brought everything else.
#260 does three things:
SparesDemand.mean()orstd()now raisesTypeError; they have been properties since 0.12.StandbyModel's andLoadSharingModel'smc_samples,lowerandseednow raiseTypeError.StandbyModel'sswitching_probabilityanddormancy_factorare now given by name.[0.13] - 2026-10-09.Type of change
Checklist
black,isortandflake8pass on the changed filescoverage run -m pytestpasses and stays above the coverage gate: the full suite runs once, on master's merge commit, before the releaseCHANGELOG.mdupdated:[0.13]Notes for reviewers
At the maintainer's request, this PR is merged without its own CI run. The full suite runs once, on master's merge commit.
release.ymlrequires that run to pass before it publishes 0.13.🤖 Generated with Claude Code
https://claude.ai/code/session_01NUGaeQXKxjjiQ1ULT1ApXS
Generated by Claude Code