Implementation Notes

How the library preserves the constructive EML chain.

This page is about engineering choices rather than mathematical existence. The central question is simple: if the paper says every standard elementary function can be built from EML, what does it take to implement that claim as a reusable Python package without quietly falling back to ordinary high-level math calls?

Backend choice: NumPy complex128

The project uses NumPy arrays and complex128 values as the execution substrate. That is an implementation choice, not a mathematical shortcut. The high-level functions are still expanded through the EML chain; NumPy provides reliable complex arithmetic, broadcasting, and IEEE-style behavior for edge cases.

In particular, the construction needs a domain where values such as log(-1) and limiting behaviors like log(0) = -inf are representable enough to support the recursive formulas.

Branch conventions

The implementation follows the principal complex branch. That keeps the EML chain aligned with the usual conventions used by scientific-computing libraries. The imaginary unit is generated with the same sign correction strategy used by the reference implementation, which avoids branch inconsistencies when reconstructing constants such as i and pi.

Why not call high-level NumPy math directly?

Because doing so would erase the point of the project. The goal here is not just to compute the right numeric answers; it is to preserve the constructive reduction from the paper all the way through the software interface.

That is why sin, cos, tanh, asin, and the rest are implemented through EML-derived arithmetic rather than delegated to numpy.sin or numpy.log at the top level. The library uses low-level exp/log primitives inside the EML operator, but the exported functions maintain the one-operator expansion.

Why expose compiler trees?

Once formulas are represented as explicit EML trees, the implementation becomes inspectable. That makes it possible to compute depth, leaf counts, graph exports, and benchmark complexity statistics. It also turns the mathematical construction into something that can be visualized, serialized, and compared across expressions.

Numerical stability choices

Some formulas are mathematically equivalent but numerically different. The most explicit example in this codebase is the logistic sigmoid.

1 / (1 + exp(-x))
0.5 * (1 + tanh(x / 2))

Both formulas are valid, but the second is materially more stable for large negative inputs once expressed through the EML chain. The library therefore keeps the second form while still remaining fully EML-based.

Complexity is part of the story

The benchmark system records tree depth, leaf count, node count, and grouped summaries because the constructive method has real structural cost. Small exponential cases remain close to the primitive; trigonometric and inverse cases expand into much larger trees.

That complexity is not a bug in the documentation. It is one of the most important engineering facts revealed by implementing the paper faithfully.

Publishability

The repository now keeps docs and benchmark assets under docs/ so they can be deployed directly through GitHub Pages. That means the published site contains both prose and real generated artifacts.

Engineering scope of this repository

The paper gives the main mathematical insight. This repository adds the software layer: stable APIs, tests, CLIs, benchmark bundles, plot generation, and a Pages-ready site that makes the construction easier to inspect and reuse.