|
1 | 1 | # Changelog |
2 | 2 |
|
3 | | -## 44.5.0 [#1368](https://github.com/openfisca/openfisca-core/pull/1368) |
4 | | - |
5 | | -#### New features |
6 | | - |
7 | | -- Add `transition_formula` to `Variable` for formula-driven `as_of` forward simulation. |
8 | | - - A variable with `transition_formula` computes sparse updates instead of full arrays: the formula returns `(selector, values)` where `selector` is a boolean mask or index array, and `values` is the new values for the selected individuals. |
9 | | - - Each call to `get_array` at a new period triggers the transition formula once (guarded by `_as_of_transition_computed`), applies the sparse diff via `set_input_sparse`, and caches the result. |
10 | | - - `set_input_sparse` is also exposed as a public method on `Holder` for callers that want to apply sparse patches directly. |
11 | | - |
12 | | -- Add `initial_formula` to `Variable` for seeding `as_of` variables without a prior `set_input`. |
13 | | - - When a `transition_formula` needs to read the variable at `period - 1` but no base snapshot exists, OpenFisca now calls `initial_formula` instead of raising an error. |
14 | | - - `initial_formula` follows the same date-dispatch convention as regular formulas (`initial_formula_YYYY`, `initial_formula_YYYY_MM`, etc.). |
15 | | - - Requires `as_of = True` on the same variable; a `ValueError` is raised at definition time otherwise. |
16 | | - |
17 | | -- Add multi-snapshot LRU cache to `as_of` variable holders. |
18 | | - - Replaces the previous single-entry snapshot cursor with an `OrderedDict`-based LRU cache keeping the K most-recently-used reconstructed snapshots. |
19 | | - - Cache size defaults to 3 and is configurable per variable (`Variable.snapshot_count`) or globally (`MemoryConfig.asof_max_snapshots`), with variable-level taking priority. |
20 | | - - Retroactive `set_input` (out-of-order writes) evicts all cached snapshots at or after the written instant to preserve correctness. |
21 | | - |
22 | | -- Add `formula_type` field to `TraceNode` for `as_of` formula visibility. |
23 | | - - When `transition_formula` or `initial_formula` runs, the tracer records `formula_type = "transition"` or `formula_type = "initial"` on the corresponding trace node. |
24 | | - |
25 | | -- Add `show_formula_type` option to `computation_log`. |
26 | | - - `simulation.tracer.computation_log.print_log(show_formula_type=True)` appends `[transition]` or `[initial]` tags to the relevant lines, making it easy to see which `as_of` formula ran during a simulation. |
27 | | - |
28 | | -#### Bug fixes |
29 | | - |
30 | | -- Fix false `SpiralError` when a `transition_formula` reads its own variable at the previous period. |
31 | | - - The existing spiral detector raised `SpiralError` immediately when the same variable appeared in the call stack at any different period, which always triggers for temporal recursion (`V@P` → `V@P-1` → `V@P-2`). |
32 | | - - Fix: in `_calculate_transition`, the cycle check is replaced by `_check_for_strict_cycle`, which only raises `CycleError` for the exact same `(variable, period)` pair. Termination is guaranteed by `_as_of_transition_computed`. |
33 | | - |
34 | | -## 44.4.1 |
35 | | - |
36 | | -#### Performance improvements |
37 | | - |
38 | | -- Fix quadratic reconstruction cost in `as_of` forward simulations. |
39 | | - - In the typical GET(M-1) → compute → SET(M) monthly loop, `_set_as_of` was unconditionally clearing the snapshot cursor after each write, forcing the next `get_array(M)` to reconstruct from the base through all M patches — O(N + M·k) per step, quadratic overall. |
40 | | - - Root cause: `_reconstruct_at` advanced the snapshot to `instant` during the internal diff computation, so the invalidation guard `snapshot[0] >= instant` triggered on equality even for strictly forward writes. |
41 | | - - Fix: when the new patch is appended at the end of the list (forward-sequential SET), the snapshot is updated to the new state instead of being discarded. Retroactive (out-of-order) writes still invalidate the snapshot correctly. |
42 | | - - Benchmark (N=1M, forward simulation): 1 yr / 10% change ×1.4, 5 yr / 10% ×4.1, 5 yr / 30% ×5.4. |
43 | | - |
44 | | -## 44.4.0 [#1366](https://github.com/openfisca/openfisca-core/pull/1366) |
45 | | - |
46 | | -#### Performance improvements |
47 | | - |
48 | | -- Replace dense array storage with sparse patch storage for `as_of` variables. |
49 | | - - Instead of storing one full array per `set_input` call, the holder now keeps a single base array and a list of `(instant, changed_indices, changed_values)` patches. |
50 | | - - Memory reduction: ~60× for a 0.5% monthly change rate over 120 months (e.g. ~4 MB vs ~240 MB for 1M individuals). |
51 | | - - GET performance: a snapshot cursor makes forward-sequential reads O(k) (only new patches applied) instead of O(N); backward jumps degrade gracefully to O(N + k×P). |
52 | | - - Retroactive `set_input` (out-of-order patches) is supported with automatic snapshot invalidation. |
53 | | - - No change to the public API (`set_input`, `get_array`, `Variable.as_of`). |
54 | | -- Fix quadratic reconstruction cost in `as_of` forward simulations: when the new patch is appended at the end (forward-sequential SET), the snapshot is updated instead of discarded so the next GET does not reconstruct from base through all patches; retroactive writes still invalidate correctly. |
55 | | - |
56 | | -## 44.4.0 [#1364](https://github.com/openfisca/openfisca-core/pull/1364) |
57 | | - |
58 | | -#### New features |
59 | | - |
60 | | -- **Entity links**: role-based and positional accessors, and dynamic population period-index helpers. |
61 | | - - `Many2OneLink.get_by_role(variable_name, period, role_value=...)`, `One2ManyLink.get_by_role(...)` and `ImplicitOne2ManyLink.get_by_role(...)`. |
62 | | - - `Many2OneLink.rank(variable_name, period)` (and on chained getter, e.g. `person.links["mother"].household.rank("age", period)`). |
63 | | - - `One2ManyLink.nth(n, variable_name, period, role=..., condition=...)` for the n-th target member per source. |
64 | | - - `has_role(role_value)` now supports `Role` objects (comparison by `.key`) in addition to raw values. |
65 | | - - `CorePopulation.snapshot_period(period)` and `get_period_id_to_rownum(period)` for optional dynamic-population period indexing. |
66 | | - |
67 | | -#### Technical changes |
68 | | - |
69 | | -- Removed unused `openfisca_core.model_api` import in `tests/core/parameters_date_indexing/test_date_indexing.py`. |
70 | | -- SimulationBuilder sets `_id_to_rownum` identity mapping for static simulations (`build_default_simulation`, `build_from_dict` / `build_from_entities`), for dynamic-population support. |
71 | | -- Add `PYTHON` variable to `tasks/lint.mk` so `make lint PYTHON=.venv/bin/python` works; fix style in `test_link_accessors.py` and remove unused variable in `test_many2one.py`. |
72 | | - |
73 | | -## 44.3.0 [#1365](https://github.com/openfisca/openfisca-core/pull/1365) |
74 | | - |
75 | | -#### New features |
76 | | - |
77 | | -- **Generic Entity Links (Phase 1-6)**: Introduced a new Liam2-inspired generic entity linking system avoiding rigid hierarchies like `Person -> Household`. |
78 | | - - Added new `Many2OneLink` and `One2ManyLink` models to create powerful inter-entity networks (e.g., `Person -> Employer`). |
79 | | - - Added implicit links directly binding members arrays. This powers the new `population.links` property natively inside `TaxBenefitSystem.instantiate_entities()`. |
80 | | - - Full capability to chain relationships via python: `person.mother.household.get("rent", period)`. |
81 | | - - Powerful vectorized declarative aggregations out-of-the-box (e.g., `households.persons.sum("salary", period, condition=is_female)`). |
| 3 | +## 44.6.0 |
82 | 4 |
|
83 | 5 | #### Technical changes |
84 | 6 |
|
85 | | -- Backward compatibility is 100% maintained. Existing syntax via Projectors natively redirects to implicit links via modified `__getattr__`. |
| 7 | +- Revert the codebase to commit `8d26af3` to align the repository with the currently published `44.2.2` baseline on PyPI. |
| 8 | +- Mark versions `44.3.0`, `44.4.0`, `44.4.1`, and `44.5.0` as yanked. |
| 9 | +- Bump version to `44.6.0` to restore continuous deployment from this reverted baseline. |
86 | 10 |
|
87 | 11 | ## 44.2.2 |
88 | 12 |
|
|
0 commit comments