Inputs. f(x), g(x), point x0; optional alignment priors a_f, a_g in [-1, +1] (default 0).
Config (declare or accept defaults).
eps_a = 1e-6 # alignment clamp
T_p = 1e-3 # exponent tie tol
T_q = 1e-3 # log-mod tie tol
R2_min = 0.85 # real-data fit quality floor
B = 200 # bootstrap (optional)
Windowing rule. Nested radii around x0 (e.g., r_k = r0 * 2^(-k)). Enforce same-window comparability: use identical neighborhoods/sample points for f and g whenever possible.
Steps (ASCII).
1) Window & sample.
Build nested neighborhoods around x0; collect paired samples of f, g on the same x (or read from symbolic form).
2) Estimate exponents (power slopes).
y_f := log|f(x)| vs t := log|x - x0| -> slope p_f, intercept log|c_f|
y_g := log|g(x)| vs t -> slope p_g, intercept log|c_g|
Use robust fits (e.g., Huber) or bootstrap to stabilize. Track signs of c_f, c_g from raw data (sign separate from |.|).
If both fits fail adequacy (R2_f < R2_min and R2_g < R2_min), set REG=NOFIT (or proceed to the model-chooser if enabled).
3) Tie-break with logs (if needed).
If |p_f - p_g| <= T_p, define L(x) := log(1/|x - x0|) and fit:
y_f' := log|f| - p_f*log|x - x0| vs log L -> slope q_f
y_g' := log|g| - p_g*log|x - x0| vs log L -> slope q_g
Compare (p_f, q_f) vs (p_g, q_g) lexicographically (see 4A).
4) Alignment (with clamps).
Choose mapping (declare one):
linear (default): a := 2*R2 - 1
contrast: a := tanh( c*(R2 - 0.5) ), c in [0.5, 2.0] (default c = 1.0; publish c)
Pick a_f from R2_f. Pick a_g from R2_g or, if using a designated reference channel (e.g., time), set a_g := +0.80 (avoid saturation at +1.0).
Clamp: a_f := clamp(a_f, -1+eps_a, +1-eps_a); a_g likewise.
Division: a_div := tanh( atanh(a_f) - atanh(a_g) )
5) Decide magnitude class.
If (p_f - p_g) > T_p -> m_out = 0
Elif (p_g - p_f) > T_p -> m_out = sign(c_f/c_g) * inf
Else # |p_f - p_g| <= T_p
If (q_f - q_g) > T_q -> m_out = sign(c_f/c_g) * inf
Elif (q_g - q_f) > T_q -> m_out = 0
Else -> m_out = c_f / c_g
Return < m_out , a_div >
Oscillation / sided checks.
- OSC test. If
var_tail(f/g)across nested windows does not shrink (or signs alternate persistently), setREG=OSCand avoid printing a singleVAL[.]. - SIDED test. Run Steps 2–5 separately on
x -> x0-andx -> x0+. If classes or signs differ, setREG=SIDEDand print both one-sided results. Optionally pool alignment via rapidity mean for an overall summary.
Implementation sketch (pseudo-code, ASCII).
INPUT: paired (x, f(x), g(x)) near x0; a_f_prior?, a_g_prior?
PARAMS: eps_a=1e-6, T_p=1e-3, T_q=1e-3, R2_min=0.85,
mapping in {linear, contrast(c=1.0)}, a_g_ref=+0.80, B=200
# 1) windows: S_all with left/right subsets if needed
def fit_power(S, h):
t = log(|x - x0|); y = log(|h(x)|)
p, b = robust_linear_fit(t, y)
c_sign = sign_from_raw(h); c = c_sign * exp(b)
R2 = r_squared(t, y)
return p, c, R2
def fit_log_mod(S, h, p):
L = log(1/|x - x0|); z = log(L)
y = log(|h|) - p*log(|x - x0|)
q, _ = robust_linear_fit(z, y)
return q
p_f, c_f, R2_f = fit_power(S_all, f)
p_g, c_g, R2_g = fit_power(S_all, g)
if |p_f - p_g| <= T_p:
q_f = fit_log_mod(S_all, f, p_f)
q_g = fit_log_mod(S_all, g, p_g)
# alignment
map_f = (2*R2_f - 1) if mapping=='linear' else tanh(c*(R2_f - 0.5))
map_g = (2*R2_g - 1) if mapping=='linear' else tanh(c*(R2_g - 0.5))
a_f = a_f_prior if a_f_prior is not None else map_f
a_g = a_g_prior if a_g_prior is not None else a_g_ref_or(map_g)
a_f = clamp(a_f, -1+eps_a, +1-eps_a)
a_g = clamp(a_g, -1+eps_a, +1-eps_a)
a_div = tanh(atanh(a_f) - atanh(a_g))
# magnitude
if (p_f - p_g) > T_p: m_out = 0
elif (p_g - p_f) > T_p: m_out = sign(c_f/c_g) * inf
else:
if (q_f - q_g) > T_q: m_out = sign(c_f/c_g) * inf
elif (q_g - q_f) > T_q: m_out = 0
else: m_out = c_f / c_g
return <m_out, a_div>
Printing (one-liner reminder).
< m_out , a_div > -> SSMS: {CLASS}@{A-tag} DIV[a_div]@{A-tag} {DIR?} {REG?}
# DIR required for INF (DIR+ / DIR-); optional for FINITE; omitted for exact ZERO.
Optional “priors sweep” (robustness).
Evaluate a_div under a_g_ref in {0.60, 0.80, 0.90} and mapping in {linear, contrast(c=0.5,1.0,2.0)}; show deltas so readers see the magnitude class is stable and alignment is not hypersensitive.
Navigation
Prev: Classifying 0over0 Limits — Model-Chooser (conservative, penalized) (4B)
Next: Classifying 0over0 Limits — Acceptance Tests (quick pass/fail) (6)