lib/simbracket/_core.pyx ports exactly the A' path of simroot.pure.pure_root (tent similarity, three-point scale, projection c=2, contra+flatanalogmempt+exp+half+close+sub, pattern) with Python's semantics kept where they differ from C: min/max keep the first argument on ties and NaN, float division by zero raises, math.log raises at 0, and math.hypot and the builtin sum (compensated since 3.12) are called rather than re-coded. find_root(f, a, b, xtol, maxfev) -> (x, nfev, converged); evaluation_bound(a, b, xtol) = 2*ceil(log2(|b-a|/xtol)) + 3. tests/test_simbracket_equivalence.py: bit-identical x and evaluation count against pure_root on all 868 problems of the six corpora (the 91 Roots.jl problems in full), at xtol 1e-12 and 1e-8 and with the budget cut to 12; errors match; the loaded module is the compiled one. 7/7 on Windows and on Linux. check_simbracket.py: removing any one component from the reference makes 36 to 455 problems differ (the test discriminates); the compiled form is 4x faster. The wheel carries only the compiled extension; _core.c is generated (gen_c.py) and ignored. Regression on the server x2: 1232 passed, 0 failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
"""Build the compiled simbracket wheel.
|
|
|
|
python gen_c.py (once, where Cython is installed)
|
|
python -m pip wheel . --no-deps --no-build-isolation -w dist
|
|
|
|
The extension is built from simbracket/_core.c when it exists, so the build machine needs a C
|
|
compiler but not Cython. Neither the .pyx nor the .c is put into the wheel. Floating-point
|
|
contraction (FMA) is switched off so that the compiled arithmetic is the IEEE arithmetic of
|
|
the Python reference, operation for operation.
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
from setuptools import Extension, setup
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
C_SRC = os.path.join("simbracket", "_core.c")
|
|
|
|
if sys.platform == "win32":
|
|
cflags = ["/O2", "/fp:precise"]
|
|
else:
|
|
cflags = ["-O2", "-ffp-contract=off", "-fno-fast-math"]
|
|
|
|
ext = Extension(
|
|
"simbracket._core",
|
|
sources=[C_SRC],
|
|
extra_compile_args=cflags,
|
|
define_macros=[("Py_LIMITED_API", "0x030A0000")],
|
|
py_limited_api=True,
|
|
)
|
|
|
|
if not os.path.exists(os.path.join(HERE, C_SRC)):
|
|
sys.exit("simbracket/_core.c is missing: run gen_c.py where Cython is installed")
|
|
|
|
setup(
|
|
name="simbracket",
|
|
version="1.0.0",
|
|
description="Bracketing root finding by similarity and analogy (compiled).",
|
|
packages=["simbracket"],
|
|
package_data={},
|
|
include_package_data=False,
|
|
ext_modules=[ext],
|
|
python_requires=">=3.10",
|
|
options={"bdist_wheel": {"py_limited_api": "cp310"}},
|
|
zip_safe=False,
|
|
)
|