Skip to content

feat: add log2 log10 sinh cosh tanh asinh acosh atanh to the formula language#41

Draft
hozblok wants to merge 1 commit into
masterfrom
feat/cpp-hyperbolic-and-additional-log-functions
Draft

feat: add log2 log10 sinh cosh tanh asinh acosh atanh to the formula language#41
hozblok wants to merge 1 commit into
masterfrom
feat/cpp-hyperbolic-and-additional-log-functions

Conversation

@hozblok
Copy link
Copy Markdown
Owner

@hozblok hozblok commented May 19, 2026

Closes TODO src/cpp/csconstants.hpp:222 (// TODO add log2 log10 sinh cosh tanh asinh acosh atanh).

Scope

Eight new one-arg math functions exposed in the formula language, both on the real and complex evaluation paths, with chain-rule derivatives where applicable.

function derivative divergence note
log2(x) 1 / (x · ln 2) throws on x = 0
log10(x) 1 / (x · ln 10) throws on x = 0
sinh(x) cosh(x)
cosh(x) sinh(x)
tanh(x) 1 / cosh(x)²
asinh(x) 1 / √(1 + x²)
acosh(x) 1 / √(x² − 1) throws on `
atanh(x) 1 / (1 − x²) throws on `

Wiring

  • csconstants.hppusing boost::multiprecision::{log2, log10, sinh, cosh, tanh, asinh, acosh, atanh};
  • cseval.hpp / cseval_complex.hppstatic _X (value) + static _X_d (derivative) per function.
  • cseval.cpp / cseval_complex.cpp — new entries in functionsOneArg and functionsTwoArgsDLeft for each.

Complex log2 / log10

Boost's cpp_complex_backend does not provide native log2 / log10. Implemented manually via the change-of-base identity log_b(z) = ln(z) / ln(b), using the existing _log primitive. Derivative uses the same identity for the constant denominator. Real log2 / log10 go through Boost's native overloads on cpp_dec_float.

Divergences

acosh / atanh derivatives are singular at x = ±1. They throw std::invalid_argument (Python-side ValueError) with the function name in the message, matching the existing _asin_d / _tan_d / _log_d convention.

Tests

Eight new files under tests/functions/one_arg/, one per function (test_log2.pytest_atanh.py). Each covers:

  • value at a convenient input (e.g. log2(8) → 3, sinh(0) → 0)
  • derivative at a convenient input where defined
  • divergence on |x| = 1 for acosh/atanh

Matches the existing terse test_X.py shape (without the long precision-256 golden values — those are easy to add later if desired).

Full suite 410/410 (+22 new), 3 xfailed unchanged.

…language

Eight new one-arg math functions wired through the standard pipeline:
  csconstants.hpp        — using boost::multiprecision::{log2, log10,
                            sinh, cosh, tanh, asinh, acosh, atanh}
  cseval.hpp             — _X static + _X_d derivative for each (real path)
  cseval_complex.hpp     — same for the complex path
  cseval.cpp             — entries in functionsOneArg + functionsTwoArgsDLeft
  cseval_complex.cpp     — same

Complex log2 / log10: Boost's cpp_complex_backend does not provide
native log2/log10. Implemented as `_log(z) / _log(base)` (the standard
change-of-base identity); derivative uses the same identity for the
constant denominator.

acosh / atanh derivatives diverge at |x|==1; they throw a clear
ValueError naming the function (matching the existing _asin_d /
_tan_d convention).

Per-function tests under tests/functions/one_arg/test_X.py for each new
function: basic value at convenient input, derivative at convenient
input, divergence on the singular cases for acosh/atanh.

Full suite 410/410 (+22 new), 3 xfailed unchanged.

Closes TODO src/cpp/csconstants.hpp:222.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant