|
1 | 1 | pymath |
2 | 2 | ====== |
3 | 3 |
|
4 | | -A binary representation compatible Rust implementation of Python's math library. |
| 4 | +**0 ULP (bit-exact) compatibility with CPython's math and cmath modules.** |
| 5 | + |
| 6 | +Every function produces identical results to Python at the binary representation level - not just "close enough", but exactly the same bits. |
5 | 7 |
|
6 | 8 | ## Overview |
7 | 9 |
|
8 | | -`pymath` is a line-by-line port of the CPython math library to Rust. This library aims to provide mathematical functions that produce identical results to Python's standard math library at the bit level. |
| 10 | +`pymath` is a strict port of CPython's math library to Rust. Each function has been carefully translated from CPython's C implementation, preserving the same algorithms, constants, and corner case handling. |
9 | 11 |
|
10 | | -## Implementation |
| 12 | +## Implemented Functions |
11 | 13 |
|
12 | | -Each function has been carefully translated from CPython's C implementation to Rust, preserving the same algorithms, constants, and corner case handling. The code maintains the same numerical properties, but in Rust! |
| 14 | +### math |
13 | 15 |
|
14 | | -## Module Structure |
| 16 | +- [x] `ceil` |
| 17 | +- [x] `copysign` |
| 18 | +- [x] `fabs` |
| 19 | +- [x] `floor` |
| 20 | +- [x] `fmod` |
| 21 | +- [x] `frexp` |
| 22 | +- [x] `isclose` |
| 23 | +- [x] `isfinite` |
| 24 | +- [x] `isinf` |
| 25 | +- [x] `isnan` |
| 26 | +- [x] `ldexp` |
| 27 | +- [x] `modf` |
| 28 | +- [x] `nextafter` |
| 29 | +- [x] `remainder` |
| 30 | +- [x] `trunc` |
| 31 | +- [x] `ulp` |
| 32 | +- [x] `cbrt` |
| 33 | +- [x] `exp` |
| 34 | +- [x] `exp2` |
| 35 | +- [x] `expm1` |
| 36 | +- [x] `log` |
| 37 | +- [x] `log10` |
| 38 | +- [x] `log1p` |
| 39 | +- [x] `log2` |
| 40 | +- [x] `pow` |
| 41 | +- [x] `sqrt` |
| 42 | +- [x] `acos` |
| 43 | +- [x] `acosh` |
| 44 | +- [x] `asin` |
| 45 | +- [x] `asinh` |
| 46 | +- [x] `atan` |
| 47 | +- [x] `atan2` |
| 48 | +- [x] `atanh` |
| 49 | +- [x] `cos` |
| 50 | +- [x] `cosh` |
| 51 | +- [x] `sin` |
| 52 | +- [x] `sinh` |
| 53 | +- [x] `tan` |
| 54 | +- [x] `tanh` |
| 55 | +- [x] `erf` |
| 56 | +- [x] `erfc` |
| 57 | +- [x] `gamma` |
| 58 | +- [x] `lgamma` |
| 59 | +- [x] `dist` |
| 60 | +- [x] `fsum` |
| 61 | +- [x] `hypot` |
| 62 | +- [x] `prod` |
| 63 | +- [x] `sumprod` |
| 64 | +- [x] `degrees` |
| 65 | +- [x] `radians` |
| 66 | +- [x] `pi` |
| 67 | +- [x] `e` |
| 68 | +- [x] `tau` |
| 69 | +- [x] `inf` |
| 70 | +- [x] `nan` |
15 | 71 |
|
16 | | -- `pymath::math` - Real number math functions (Python's `math` module) |
17 | | -- `pymath::cmath` - Complex number functions (Python's `cmath` module, requires `complex` feature) |
18 | | -- `pymath::m` - Direct libm bindings |
| 72 | +### math.integer (requires `num-bigint` or `malachite-bigint` feature) |
| 73 | + |
| 74 | +- [x] `comb` |
| 75 | +- [x] `factorial` |
| 76 | +- [x] `gcd` |
| 77 | +- [x] `isqrt` |
| 78 | +- [x] `lcm` |
| 79 | +- [x] `perm` |
| 80 | + |
| 81 | +### cmath (requires `complex` feature) |
| 82 | + |
| 83 | +- [x] `abs` |
| 84 | +- [x] `isclose` |
| 85 | +- [x] `isfinite` |
| 86 | +- [x] `isinf` |
| 87 | +- [x] `isnan` |
| 88 | +- [x] `phase` |
| 89 | +- [x] `polar` |
| 90 | +- [x] `rect` |
| 91 | +- [x] `exp` |
| 92 | +- [x] `log` |
| 93 | +- [x] `log10` |
| 94 | +- [x] `sqrt` |
| 95 | +- [x] `acos` |
| 96 | +- [x] `acosh` |
| 97 | +- [x] `asin` |
| 98 | +- [x] `asinh` |
| 99 | +- [x] `atan` |
| 100 | +- [x] `atanh` |
| 101 | +- [x] `cos` |
| 102 | +- [x] `cosh` |
| 103 | +- [x] `sin` |
| 104 | +- [x] `sinh` |
| 105 | +- [x] `tan` |
| 106 | +- [x] `tanh` |
19 | 107 |
|
20 | 108 | ## Usage |
21 | 109 |
|
22 | 110 | ```rust |
23 | | -use pymath::math::{gamma, lgamma}; |
| 111 | +use pymath::math::{sqrt, gamma, lgamma}; |
24 | 112 |
|
25 | 113 | fn main() { |
26 | | - // Get the same results as Python's math.gamma and math.lgamma |
| 114 | + let sqrt_result = sqrt(2.0).unwrap(); |
27 | 115 | let gamma_result = gamma(4.5).unwrap(); |
28 | 116 | let lgamma_result = lgamma(4.5).unwrap(); |
29 | 117 | } |
30 | 118 | ``` |
| 119 | + |
| 120 | +### Bit-exact verification |
| 121 | + |
| 122 | +```python |
| 123 | +# Python 3.14 |
| 124 | +>>> import math |
| 125 | +>>> math.gamma(0.5).hex() |
| 126 | +'0x1.c5bf891b4ef6ap+0' |
| 127 | +``` |
| 128 | + |
| 129 | +```rust |
| 130 | +// Rust - identical bits |
| 131 | +assert_eq!( |
| 132 | + pymath::math::gamma(0.5).unwrap().to_bits(), |
| 133 | + 0x3ffc5bf891b4ef6a |
| 134 | +); |
| 135 | +``` |
| 136 | + |
| 137 | +*Bit representation may vary across platforms, but CPython and pymath built on the same environment will always produce identical results.* |
| 138 | + |
| 139 | +## Features |
| 140 | + |
| 141 | +- `complex` (default) - Enable cmath module for complex number functions |
| 142 | +- `num-bigint` - Enable integer functions using num-bigint |
| 143 | +- `malachite-bigint` - Enable integer functions using malachite-bigint |
| 144 | +- `mul_add` - Use hardware FMA for bit-exact macOS compatibility |
| 145 | + |
| 146 | +## Module Structure |
| 147 | + |
| 148 | +- `pymath::math` - Real number math functions (Python's `math` module) |
| 149 | +- `pymath::cmath` - Complex number functions (Python's `cmath` module) |
| 150 | +- `pymath::m` - Direct libm bindings |
0 commit comments