内容
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/pycodemath-lockup.svg">
<img alt="pycodemath" src="assets/pycodemath-lockup-light.svg" width="420">
</picture>
</p>
<p align="center">
<strong>适用于AI智能体的高效精确数学运算。</strong>
</p>
<p align="center">
<a href="https://pypi.org/project/pycodemath/"><img alt="PyPI" src="https://img.shields.io/pypi/v/pycodemath.svg?color=e11d33"></a>
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-e11d33.svg"></a>
<img alt="Python 3.11+" src="https://img.shields.io/badge/python-3.11%2B-3776ab.svg">
<img alt="230 tests passing" src="https://img.shields.io/badge/tests-230%20passing-2ea043.svg">
<img alt="mypy: clean" src="https://img.shields.io/badge/mypy-clean-2ea043.svg">
<a href="https://github.com/cybersora9/pycodemath/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/cybersora9/pycodemath/actions/workflows/ci.yml/badge.svg"></a>
</p>
用几字符写数学,获得精确答案或独立、优化的Python/NumPy代码返回 — 而不是要求语言模型“在脑海中进行算术”或手写数值循环。
在SymPy + NumPy的基础上构建了一个薄而有纪律的层:
1. **减少Token消耗** — 一个简短的命令输入,一个精确的结果输出。作为智能体工具非常完美(包括MCP服务器)。
2. **比朴素Python更好的代码** — 生成器在发出代码之前应用符号简化 + 公共子表达式消除(CSE),比朴素扩展在重复子表达式上快约1.7倍。
```
文本 → [解析器] → IR(表达式树)→ [引擎] 求值 / 简化 / 求解
→ [生成器] IR → CSE → Python/NumPy源代码
```
## 安装
```bash
pip install pycodemath # 核心:sympy + numpy
pip install pycodemath[mcp] # + 用于AI智能体的MCP服务器
```
从克隆仓库开始,用于开发(可编辑安装):
```bash
pip install -e .[dev] # 可编辑 + pytest + mypy
```
需要Python ≥ 3.11。
## 快速开始
### 一次性CLI(可脚本化)
以下每个命令都是带有真实输出的实际调用。
```console
$ python -m pycodemath "diff sin(x)*x dx"
x*cos(x) + sin(x)
$ python -m pycodemath "integrate 2*x dx"
x**2
$ python -m pycodemath "solve x^2 - 4 for x"
-2, 2
$ python -m pycodemath "sin(x)^2 + cos(x)^2"
1
$ python -m pycodemath "eig [[2,1],[1,2]]"
3, 1
$ python -m pycodemath "solve_nd x^2+y^2-4; x-y for x,y at 1,1"
x = 1.4142135623746899, y = 1.4142135623746899
```
错误信息会输出到stderr,退出码为1;结果输出到stdout,退出码为0 — 可以安全地从脚本和智能体工具中调用。在Windows控制台上设置`PYTHONUTF8=1`。
### REPL
```bash
python -m pycodemath # 或直接:pycodemath
```
输入`help`查看完整的命令表格(导数、积分、方程求解、矩阵、根查找、优化、整个ODE套件和代码生成)。
### MCP服务器(适用于任何AI智能体的数学运算)
```bash
pip install -e .[mcp]
claude mcp add pycodemath -- python -m pycodemath.cli.mcp_server
```
暴露一个名为`math_eval`的工具,接受与REPL相同的命令 — 智能体发送`diff sin(x)*x dx`并接收精确的`x*cos(x) + sin(x)`,无需任何心理算术。
### 作为Claude Code技能使用
上述MCP服务器是可移植的路径 — 它可以插入到**任何**MCP客户端。如果你特别使用[Claude Code](https://claude.com/claude-code),你也可以将Pycodemath作为一个**技能**,这样Claude在需要实际数学时可以调用引擎(无需运行MCP进程)。
**它改变了什么:** 与其“在脑海中”计算 — 大型模型可以悄悄地在算术、积分或特征值上出错 — Claude将任务委托给引擎并粘贴回一个确切的SymPy/NumPy结果。一个短命令输入,一行确切输出:更少的Token,无沉默错误。
**部署(一次):**
```bash
pip install pycodemath # 或:pip install -e . (从克隆仓库)
mkdir -p ~/.claude/skills/pycodemath
```
将以下内容保存为`~/.claude/skills/pycodemath/SKILL.md`:
```markdown
---
名称: pycodemath
描述: 使用本地Pycodemath引擎(SymPy+NumPy)进行数学运算,而不是在脑海中 — 导数,积分,方程和系统求解(线性和非线性),行列式/逆/特征值,梯度/雅可比/海森矩阵,函数极小值,ODE和优化的Python/NumPy代码生成(CSE)。在用户要求计算或验证符号/数值数学或从公式生成代码时使用。
# Pycodemath — 本地数学引擎
一个命令 = 一个调用(该软件包已通过pip安装,因此任何工作目录都可以):
python -m pycodemath "<命令>"
结果输出到stdout(退出码0);错误输出到stderr(退出码1)。幂表示法:`^` 或 `**`。在Windows控制台上,设置 `PYTHONUTF8=1`。
## 命令
| 命令 | 示例 |
|---|---|
| `<表达式>` — 简化 | `python -m pycodemath "sin(x)^2 + cos(x)^2"` → `1` |
| `diff <表达式> d<变量>` — 导数 | `"diff sin(x)*x dx"` → `x*cos(x) + sin(x)` |
| `integrate <表达式> d<变量>` — 符号积分 | `"integrate 2*x dx"` → `x**2` |
| `solve <表达式> for <变量>` — 求解 = 0 | `"solve x^2-4 for x"` → `-2, 2` |
| `code <表达式>` — CSE优化的NumPy代码 | `"code (sin(x)+cos(x))^2"` |
| `det / inv / transpose / eig <A>` | `"eig [[2,1],[1,2]]"` → `3, 1` |
| `solve_system <A> = <b>` — 线性系统 | `"solve_system [[2,1],[1,3]] = [3,5]"` |
| `root <表达式> for <变量> at <x0>` — 数值根 | `"root x^2-2 for x at 1"` |
| `min <表达式> for <变量> at <x0> [方法 newton|bfgs]` — 1D极小值 | `"min (x-3)^2 for x at 0"` |
| `grad <表达式> for <x,y,...>` — 符号梯度 | `"grad x^2*y for x,y"` |
| `solve_nd <f1>; <f2> for <x,y> at <x0,y0>` — 非线性系统 | `"solve_nd x^2+y^2-4; x-y for x,y at 1,1"` |
| `min_nd <表达式> for <x,y> at <x0,y0> [方法 newton|bfgs]` — N-D极小值 | `"min_nd (1-x)^2+100*(y-x^2)^2 for x,y at -1.2,1 method bfgs"` |
| 极限/级数/和/ODE | `"limit sin(x)/x for x to 0"`,`"sum 1/k^2 for k from 1 to oo"` |
在REPL中输入`help`(`python -m pycodemath`)查看完整的命令表格。
## 规则
- **何时使用:** 用户需要一个具体的数学结果(导数,积分,方程,矩阵,最小值,ODE)或从公式生成的优化代码。引擎是精确的 — 相信其输出优于脑算。
- **何时不使用:** 琐碎的算术或概念性问题,无需计算。
- 以stderr输出的`error: ...`行(退出码1)通常意味着命令中有一个错误,一个数值方法未收敛,或没有实数解 — 阅读信息,它是具体的。
重启Claude Code(或打开新会话),它将在需要精确数学时自动调用该技能。要确认它已注册,运行`/help`并在技能列表中查找`pycodemath`。
## 极限,级数和符号和
除了`diff`/`integrate`/`solve`之外,引擎还处理极限(包括单侧和无穷大),泰勒/洛朗展开式和符号求和 — 有限或无限。所有实际调用都有实际输出:
```console
$ python -m pycodemath "limit (1+1/n)^n for n to oo"
E
$ python -m pycodemath "series exp(x) for x n 4"
x**3/6 + x**2/2 + x + 1
$ python -m pycodemath "sum k for k from 1 to n"
n**2/2 + n/2
$ python -m pycodemath "sum 1/k^2 for k from 1 to oo"
pi**2/6
```
发散的和或不存在的极限会以可读的错误信息拒绝,而不是返回符号回声。
## 优化:牛顿和BFGS在梯度下降停滞时
`min` / `min_nd` 默认使用普通的梯度下降;`method newton|bfgs` 切换到二阶方法,并使用Armijo回溯线搜索。在Rosenbrock山谷(从 `(-1.2, 1)` 开始)梯度下降在10,000次迭代后拒绝,而BFGS在36次迭代中收敛:
```console
$ python -m pycodemath "min_nd (1-x)^2 + 100*(y-x^2)^2 for x,y at -1.2,1 method bfgs"
x = 0.999999999999454, y = 0.9999999999989762
```
## ODE套件
符号(`dsolve`)加全数值工具箱 — 标量和系统,正向和反向时间(`t1 < t0`),所有拒绝静默跳转过奇点(可读错误信息而不是垃圾):
| 求解器 | 功能 |
| --- | --- |
| `solve_ode_num` | 经典固定步RK4 |
| `solve_ode_adaptive` | Dormand–Prince 5(4),自适应步长(类似`ode45`) |
| `solve_ode_dense` | 自适应 + 密集输出:可调用`sol(t)` 任意位置 |
| `solve_ode_events` | 事件检测 `g(t,y)=0` (+ 终端事件) |
| `solve_ode_stiff` | 隐式BDF2 + 牛顿法用于刚性方程 |
| `solve_ode_stiff_adaptive` | **变步长BDF2**,局部误差控制 |
| `solve_ode_system_*` | 所有上述的矢量变体 |
平滑问题的自适应积分在`rtol 1e-8`下需要41步:
```console
$ python -m pycodemath "ode_adaptive y*cos(t) for y(t) from 0 to 5 at 1 rtol 1e-8"
y(5) = 0.3833049965035854 (41 自适应步长)
```
在经典的刚性问题 `y' = -1000(y - cos t)` 上,显式对被稳定性限制(`rtol 1e-6`下378步;相同预算下固定步RK4返回天文学上错误的值)。自适应BDF在313步内完成 — 从慢流形开始,刚性纯粹时,在**58步 vs 357步**:
```console
$ python -m pycodemath "odestiff_adaptive -1000*(y-cos(t)) for y(t) from 0 to 1 at 0"
y(1) = 0.5411432587540607 (自适应BDF,313隐式步长)
```
系统变体处理Van der Pol振荡器,μ=1000,在`[0, 2000]`上,需要5,332步(~1秒) — 显式方法需要≥2,000,000步。
## 代码生成
`code <表达式>` 发出独立的、CSE优化的NumPy源代码(实际输出):
```console
$ python -m pycodemath "code (sin(x)+cos(x))^2 + (sin(x)+cos(x))^3"
import numpy as np
def f(x):
"""Pycodemath: f(x) — NumPy代码."""
_c0 = np.sin(x + (1/4)*np.pi)
return 2*_c0**2*(np.sqrt(2)*_c0 + 1)
```
Python API还生成独立的ODE积分器 — 包括具有**密集输出**的自适应积分器,其发射的插值与引擎的插值相同(测量最大差异:节点上和节点外网格上均为`0.0`):
```python
from pycodemath import parse, generate_ode_dense
art = generate_ode_dense(parse("y*cos(t)"), "t", "y")
sol = art(1.0, 0.0, 5.0, 1e-8) # 独立的DOPRI5,返回插值函数
sol(2.5) # -> 1.8193369962907706
len(sol.ts) # -> 42 个接受的节点
```
事件检测来自API:
```python
from pycodemath import parse, solve_ode_events
ev = solve_ode_events(parse("cos(t)"), "t", 0.0, (0.0, 10.0), parse("y"), rtol=1e-8)
ev.event_times # -> [3.141593, 6.283185, 9.424778] (π, 2π, 3π)
```
## 设计契约
- 引擎和生成器共享一个IR(`Expr`/`Matrix`)。
- 数值循环在编译函数上运行(`lambdify` + LRU缓存)— 每个迭代零SymPy调用。
- 分歧或域问题引发可读的`PycodemathError` — 结果中从不出现NaN/垃圾。
- 解析器仅解析白名单中的数学函数 — 未知名称成为符号,不是Python代码;字符串文字和属性访问直接拒绝,评估成本有界限,因此单个表达式(例如`9**9**9`)无法耗尽内存。
- 测试首先测量实数,然后使用边距断言它们 — **230个测试**,所有测试都在Ubuntu和Windows上通过(包括CI和mypy)。
## 许可证
MIT — 见 [LICENSE](LICENSE)。