Operator Calculus, Co.
Browse Studio documentation
On this page

These helpers expose the public math-primitive surface available in Oakfield. Scalar helpers return a number for real inputs and a two-element complex table {re, im} for complex inputs. Domain and convergence failures raise Lua errors instead of returning silent NaNs.

At a Glance

Family Functions
Polygamma digamma, trigamma, digamma_batch, trigamma_batch
Generalized harmonic generalized_harmonic, generalized_harmonic_batch, generalized_harmonic_d1, generalized_harmonic_d1_batch, generalized_harmonic_d2, generalized_harmonic_d2_batch
Hyperexponential hyperexp, hyperexp_deriv
q-hyperexponential qhyperexp, qhyperexp_deriv, qhyperexp_deriv_complex
Other q-analogs qnumber, qzeta, qdigamma

Batch Inputs & Outputs

Batch helpers share the same container contract:

family_batch(values, [out]) -> results_or_out
generalized_harmonic_batch(values, K, [out]) -> results_or_out
generalized_harmonic_d1_batch(values, K, [out]) -> results_or_out
generalized_harmonic_d2_batch(values, K, [out]) -> results_or_out
  • values may be a Lua array, a Field handle, or a field_view descriptor from ooc.field_view_from_field(field).
  • If out is omitted, Oakfield returns a new Lua array.
  • If out is provided, Oakfield fills it in place and returns that same array, Field, or field_view.
  • Complex results require a complex-capable output buffer. A real output view cannot receive complex values.

For throughput-sensitive loops, prefer Field or field_view inputs over Lua arrays to avoid per-element Lua marshalling.

Polygamma

digamma(z) -> number | {re, im}
trigamma(z) -> number | {re, im}
digamma_batch(values, [out]) -> array | Field | field_view
trigamma_batch(values, [out]) -> array | Field | field_view

The classical polygamma entry points are:

ψ(z)=ddzlog⁡Γ(z),ψ1(z)=ddzψ(z).\psi(z) = \frac{d}{dz}\log \Gamma(z), \qquad \psi_1(z) = \frac{d}{dz}\psi(z).

Both helpers accept real or complex inputs. The batch forms evaluate the same kernels over a container of values.

local psi = ooc.digamma(1.5)
local psi_c = ooc.digamma({0.75, 0.25})

local psi_many = ooc.digamma_batch({1.5, 2.5, {0.75, 0.25}})

local src = ooc.add_field(ctx, {3}, { type = "real_double", fill = 0.0 })
src:set_values({1.5, 2.0, 2.5})

local dst = ooc.add_field(ctx, {3}, { type = "real_double", fill = 0.0 })
ooc.digamma_batch(ooc.field_view_from_field(src), ooc.field_view_from_field(dst))

Avoid poles at the non-positive integers. Away from poles, digamma and trigamma are the most routine research-grade primitives in this section.

Generalized Harmonic Ladder

generalized_harmonic(a, K) -> number | {re, im}
generalized_harmonic_batch(values, K, [out]) -> array | Field | field_view
generalized_harmonic_d1(a, K) -> number | {re, im}
generalized_harmonic_d1_batch(values, K, [out]) -> array | Field | field_view
generalized_harmonic_d2(a, K) -> number | {re, im}
generalized_harmonic_d2_batch(values, K, [out]) -> array | Field | field_view

Oakfield exposes the finite generalized harmonic ladder

HK(a)=∑n=0K−11a+n=ψ(a+K)−ψ(a),H_K(a) = \sum_{n=0}^{K-1}\frac{1}{a+n} = \psi(a + K) - \psi(a),

together with its first two derivatives with respect to a:

∂∂aHK(a)=ψ1(a+K)−ψ1(a),\frac{\partial}{\partial a}H_K(a) = \psi_1(a + K) - \psi_1(a), ∂2∂a2HK(a)=ψ2(a+K)−ψ2(a).\frac{\partial^2}{\partial a^2}H_K(a) = \psi_2(a + K) - \psi_2(a).

The derivative families use the same real/complex continuation rules as the scalar ladder.

local H = ooc.generalized_harmonic(0.75, 8)
local dH = ooc.generalized_harmonic_d1(0.75, 8)
local d2H = ooc.generalized_harmonic_d2({0.75, -0.25}, 8)

local sweep = ooc.generalized_harmonic_batch({0.5, 0.75, 1.0}, 8)
  • K must be non-negative.
  • For real inputs, a must stay positive.
  • Complex inputs use analytic continuation away from poles.

Hyperexponential

hyperexp(lambda, epsilon, K) -> number | {re, im}
hyperexp_deriv(lambda, epsilon, K) -> number

Oakfield uses the finite hyperexponential helper

ϕ(λ,ε;K)=∑k=0K−1λλ+ε+k.\phi(\lambda,\varepsilon;K) = \sum_{k=0}^{K-1} \frac{\lambda}{\lambda + \varepsilon + k}.

hyperexp is the preferred name. The older hyperexp_phi and hyperexp_phi_complex spellings are compatibility aliases for the same evaluator.

The derivative helper is with respect to lambda and is currently real-only:

local phi = ooc.hyperexp(2.0, 0.5, 8)
local phi_c = ooc.hyperexp({1.2, 0.3}, {0.8, -0.1}, 8)
local dphi = ooc.hyperexp_deriv(1.5, 0.4, 6)
  • K must be positive.
  • Non-finite results raise Lua errors.
  • Near singular parameter regimes, treat hyperexp* as exploratory rather than a blind drop-in numeric primitive.

q-Hyperexponential

qhyperexp(lambda, epsilon, K, q) -> number | {re, im}
qhyperexp_deriv(lambda, epsilon, K, q) -> number
qhyperexp_deriv_complex(lambda, epsilon, K, q) -> {re, im}

The q-deformed ladder is

ϕq(λ,ε;K,q)=∑k=0K−1λλ+εqk.\phi_q(\lambda,\varepsilon;K,q) = \sum_{k=0}^{K-1} \frac{\lambda}{\lambda + \varepsilon q^k}.

qhyperexp is the preferred name. The older qhyperexp_phi and qhyperexp_phi_complex spellings remain as aliases. Likewise, qhyperexp_phi_deriv and qhyperexp_phi_deriv_complex are legacy aliases of the canonical derivative names.

local qphi = ooc.qhyperexp(1.5, 0.2, 12, 0.9)
local qphi_c = ooc.qhyperexp({0.6, 0.4}, {0.3, -0.2}, 12, 0.9)
local qd = ooc.qhyperexp_deriv(1.5, 0.2, 12, 0.9)
local qd_c = ooc.qhyperexp_deriv_complex({0.6, 0.4}, {0.3, -0.2}, 12, 0.9)
  • K must be positive.
  • qhyperexp_deriv is real-only.
  • qhyperexp_deriv_complex always returns a complex pair.
  • q-regime sensitivity is higher than in the classical families, so treat fault boundaries and validation checks as part of the workflow.

Other q-Analogs

Jackson q-Number

qnumber(value, q) -> number | {re, im}
[x]q=1−qx1−q,[x]_q = \frac{1 - q^x}{1 - q},

with the identity limit [x]_1 = x preserved by the safe evaluator.

local qn = ooc.qnumber(1.5, 0.8)
local qn_c = ooc.qnumber({0.5, 0.2}, 0.8)

q-Deformed Hurwitz Zeta

qzeta(s, a, q) -> number
ζq(s,a)=∑n=0∞q(n+a)(s−1)[n+a]q s.\zeta_q(s,a) = \sum_{n=0}^{\infty} \frac{q^{(n+a)(s-1)}}{[n+a]_q^{\,s}}.
local z = ooc.qzeta(2.5, 0.75, 0.9)

qzeta is real-only. When convergence fails, the Lua error includes the reported fault, iteration count, and residual.

q-Digamma

qdigamma(z, q) -> number | {re, im}
ψq(z)=−ln⁡(1−q)+ln⁡(q)∑n=0∞qn+z1−qn+z.\psi_q(z) = -\ln(1 - q) + \ln(q)\sum_{n=0}^{\infty} \frac{q^{n+z}}{1 - q^{n+z}}.
local qpsi = ooc.qdigamma(1.25, 0.9)
local qpsi_c = ooc.qdigamma({1.0, -0.25}, 0.9)

Like qzeta, qdigamma uses safe evaluators and raises explicit Lua errors when q-domain rules or convergence limits are violated.

Compatibility Aliases

Preferred name Compatibility aliases
hyperexp hyperexp_phi, hyperexp_phi_complex
hyperexp_deriv hyperexp_phi_deriv
qhyperexp qhyperexp_phi, qhyperexp_phi_complex
qhyperexp_deriv qhyperexp_phi_deriv
qhyperexp_deriv_complex qhyperexp_phi_deriv_complex

Fault Model

Standalone math helpers raise Lua errors immediately when inputs fall outside their supported domains. The context-managed fault counters, fallback hooks, and pole utilities documented in special/context are for context-owned operator/runtime evaluation, not for bypassing these direct helper errors.