feat(solve): monte_carlo 系列两个函数落地(L0 11/12、L1)+ Wilson 区间;修 z_score^2 异或 bug
用户实现: - solve.monte_carlo(L0 第 11 项,S 档):向量化采样→仿真→汇总,8 个指标; 批量大小由实现传 sampler(rng, size=n);结果含 NaN 判失败;std 用 ddof=0。 - solve.monte_carlo_probability(L1,S 档):event(batch)->bool,Wilson score 区间夹 [0,1], confidence 记进 params,小概率改成 message 警告。 Codex 只碰工程侧(算法未动,唯一例外见下): - 真 bug:z_score^2 是异或不是乘方(np.float64 ^ 2 抛 TypeError,被 except 吞成 success=False, 函数实际不可用)-> 改 z_score**2。新增经验第 21 条。 - docstring:补齐 Parameters / Raises,修掉两处跑不通的 Examples,Wald -> Wilson 同步。 - 入口校验按 §4.7 收严 n(bool / np.integer / TypeError 与 ValueError 分工)—— 决策 49 后此类归用户,已记档。 - ruff 九条(I001 / F541 x3 / SIM300 / W291 x2 / W293 x2 等)、格式与文案。 - 测试:摘掉 2 条已实现却仍挂着的 skip(易错点 9),新增 14 条(含 vectorization、 Wilson 对 statsmodels 的对照、NaN / 布尔 / 长度等边界),solve 段共 25 条。 校验:193 收集 / 161 passed / 32 skipped / 0 xfail;ruff 0;pyright 0。 文档:STATUS.md 决策 47-50;docs/dev/personal-pitfalls.md 第 18-21 条;CHANGELOG.md。
This commit is contained in:
1 parent
58f2236703
commit
b0c4b4a413
5 files changed
+619
-61
No files matched your search
@@ -338,6 +338,67 @@
|
||||
(`monte_carlo` 的契约 / 向量化要求 / 三条测试建议 / 卡片路径 / 一个待拍板口径);
|
||||
验证结果里的 skip 说明由 37 条订正为 **34 条**。
|
||||
|
||||
### Added
|
||||
- `solve.monte_carlo` 落地(**L0 第 11 项,S 档**,实现由用户本人写):向量化"采样 → 仿真 → 汇总",
|
||||
返回 `Result`(8 个 metrics:mean / std / median / p05 / p95 / ci_low / ci_high),随机数无条件走 `get_rng`。
|
||||
配套 `tests/test_solve.py` **10 条**测试(含"`simulator` 只被调用一次"这条可执行的向量化断言)。
|
||||
|
||||
### Fixed
|
||||
- `monte_carlo` 的**布尔结果**此前让 `np.std` 在 numpy 2 里抛 `numpy boolean subtract ... is not supported`,
|
||||
整个函数判失败 —— 而"事件是否发生"是 MC 最常见的用法。入口改为 `np.asarray(..., dtype=float)`(布尔按 0/1 统计);
|
||||
字符串结果也从"ufunc isnan 不支持"变成可读的 `could not convert string to float`。由行为探针挖出。
|
||||
- `monte_carlo` 的 docstring `Examples` 跑不通:原采样器返回标量,实测 `success=False`
|
||||
("simulator 返回的结果数量(1)必须与模拟次数 n(1000)一致");改成向量化写法。
|
||||
- `monte_carlo` 的 ruff 三条(I001 合并同源 import、F541 空 f-string ×2)、`success= True` 的空格、
|
||||
失败文案"重采样" → "模拟"(从 `bootstrap_ci` 抄过来忘改)。
|
||||
|
||||
### Changed
|
||||
- `monte_carlo` 按 §4.7 收严 `n`:`np.int64` 不再被误拒(注解放宽为 `int | np.integer`);
|
||||
`n=True` / 浮点 `n` 抛 `TypeError`;`n<=0` 抛 `ValueError`。
|
||||
- 用户第二轮改的三处口径(决策 48):批量大小改由实现传 `sampler(rng, size=n)`;结果含 NaN 判 `success=False`;
|
||||
`np.std` 显式 `ddof=0`。docstring 同步改写(`sampler` 契约、`Raises`、`Notes` 的 NaN 口径)。
|
||||
- `STATUS.md`:L0 10/12 → **11/12**,新增决策 48;验证计数更新为 **187 收集 / 153 passed / 34 skipped**。
|
||||
|
||||
### Changed
|
||||
- 工作约定收窄(**决策 49**):**入口没收紧 / 少考虑情况 / 不符合简单原则**这三类改动交回用户本人写,
|
||||
Codex 只报告 + 列选项(判据:这处改动要不要"想一下才对")。决策 47 里"入口 / 校验重构归 Codex"的部分作废。
|
||||
- `docs/dev/personal-pitfalls.md`:新增 **第 18 / 19 / 20 条**(入口校验没照 §4.7 清单逐条过 / 只想着主路径那种值 /
|
||||
"不简单"的信号是同一个信息要写两遍),第 1 条(类型判断只写 `int`)**复发 +1**,索引补到 20。
|
||||
- `STATUS.md`:新增决策 49 与两个待拍板小口径(`random_state` 注解是否全项目对齐、`std` 的 `ddof` 是否统一)。
|
||||
|
||||
### Added
|
||||
- `solve.monte_carlo_probability` 落地(**L1,S 档**,实现由用户本人写):向量化 `event(batch) -> bool 数组`,
|
||||
返回 `Result`(`probability` / `ci_low` / `ci_high` / `std_error`),区间是 Wald 区间并夹在 `[0, 1]`(沿用决策 42 口径)。
|
||||
`tests/test_solve.py` 新增 5 条 + **摘掉 2 条 skip**(实现已写完却还挂着,易错点 9),`solve` 段共 24 条。
|
||||
|
||||
### Fixed
|
||||
- `monte_carlo_probability` 的 docstring `Examples` 跑不通:原采样器返回标量,实测 `success=False`
|
||||
("event 返回的结果数量(1)必须与模拟次数 n(2000)一致");改成批量采样写法并实测通过。
|
||||
- `monte_carlo_probability` 的 ruff 六条:SIM300(`0.0 >= confidence` 写成 Yoda 条件)、W291 ×2、W293 ×2、F541。
|
||||
- 该函数 NaN 提示里的 "simulator" 改成 "event"(从 `monte_carlo` 抄来没改);`metrics` 缩进与 `{"n":n}` 空格。
|
||||
|
||||
### Changed
|
||||
- `monte_carlo_probability` 的 docstring 补齐 `Parameters` / `Raises`(原文只有 Returns / Notes / Examples),
|
||||
并把"Wald 区间 + 夹到 [0,1]"与"`p <= 1e-3` 判失败"两条现状如实写进 Returns / Notes。
|
||||
- `STATUS.md`:L1 清单加入 `monte_carlo_probability`;验证计数更新为 **192 收集 / 160 passed / 32 skipped**;
|
||||
「下一步」新增该函数的 **6 条待办口径**(全部留给用户,Codex 未动)。
|
||||
|
||||
### Fixed
|
||||
- **`monte_carlo_probability` 的 `z_score^2` 是异或不是乘方**(Python `^` 语义):`np.float64 ^ 2` 直接抛
|
||||
`TypeError: ufunc 'bitwise_xor' not supported`,被 `except Exception` 吞成 `success=False` —— 函数实际上**整个不可用**,
|
||||
6 条测试全红才暴露。改成 `z_score**2`。新增经验第 21 条。
|
||||
- `monte_carlo_probability` 的 message 在没有警告时留了个尾逗号;`{"confidence":confidence}` 补空格。
|
||||
|
||||
### Changed
|
||||
- 用户第二轮改定(**决策 50**):区间由 **Wald 换成 Wilson score**(实测 p=1、n=1000 从退化的 `(1.0, 1.0)`
|
||||
变成 `(0.99617, 1.0)`;p=0 从"判失败"变成 `(0.0, 0.00383)`);小概率不再判失败,改为 message 里的警告;
|
||||
`confidence` 记进 `Result.params`;`callable` 入口校验(现在抛 `TypeError`);`float()` 统一 `ci_*` 类型;
|
||||
`n` 注解放宽为 `int | np.integer`。
|
||||
- `tests/test_solve.py`:新增 1 条对照测试(区间必须等于 `statsmodels.proportion_confint(method="wilson")`),
|
||||
共 25 条;全量 **193 收集 / 161 passed / 32 skipped / 0 xfail**。
|
||||
- `docs/dev/personal-pitfalls.md`:新增第 **21** 条(公式里的 `^` 不是乘方,且被 `except` 吞成 `success=False`),索引补到 21。
|
||||
- docstring 的 "Wald 区间" 同步改为 "Wilson score 区间"。
|
||||
|
||||
## [0.0.1] - 2026-10-01
|
||||
|
||||
### Added
|
||||
|
||||
Reference in new issue
Block a user