fix: replace divergent fixed-point iteration with bisection in fixed_point_approx#15
Open
shayan0373n wants to merge 1 commit intoglandfried:masterfrom
Open
Conversation
…point_approx The original fixed-point iteration in fixed_point_approx diverges when r*sigma^2 is large (e.g. Discrete scores >= 3 with sigma < 0.5). The fixed-point map becomes non-contractive and oscillates, eventually causing a math domain error in log() or producing wildly incorrect posterior estimates. Replace the direct iteration with bisection on g(kappa) = f(kappa) - kappa, which is guaranteed to converge since g is monotonically decreasing. The root always exists in [-20, 20] for practical inputs. This fix: - Eliminates ValueError: math domain error for Discrete observations - Produces correct posteriors (verified against scipy.optimize.brentq) - Adds no new dependencies (pure math.sqrt + math.log) - Converges to ~1e-10 tolerance in ~50 bisection steps (microseconds)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
fixed_point_approxuses direct fixed-point iteration to solve for kappa in the Gaussian approximation of Poisson observations (Discrete model). Whenr * sigma²is large — which happens naturally as sigma shrinks during inference with score differences >= 3 — the fixed-point map becomes non-contractive: its derivative exceeds 1 in magnitude, causing the iteration to oscillate between two values that never converge.This leads to either:
ValueError: math domain error(log of a negative number)Reproduction
Root Cause
The fixed-point equation is:
The map
f(kappa)has a unique fixed point, but|f'(kappa*)| > 1for many practical parameter combinations, making direct iteration divergent. The fixed point still exists — the iteration just can't reach it.Fix
Replace direct iteration with bisection on
g(kappa) = f(kappa) - kappa:gis monotonically decreasing (proven by the structure of the equation)[-20, 20]for practical inputs~1e-10tolerance (microseconds of compute)math.sqrtandmath.logVerified against scipy.optimize.brentq