Skip to content

Over the reals, a modulus of a polynomial is split at the polynomial's real roots - #2178

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
a-modulus-of-a-polynomial-is-split-at-its-real-roots
Oct 27, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
a-modulus-of-a-polynomial-is-split-at-its-real-roots

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Part of #2139: the real codomain.

The defect: with the real codomain, ModulusSolver.SolveOverTheReals solves an equation in moduli by cases between the kinks, but only where every modulus is of a linear function. A modulus of anything else fell through to Newton's method, and the answer kept non-real entries that solve nothing:

Solve, with the real codomain 2.6.0 this PR
x^2/abs(1-x^2) = x { 0, 0.618…, 1.618…, 1.618… + 1.7E-9i, 1.618… + 9.9E-8i } { 0, (-1 + sqrt(5)) / 2, (1 + sqrt(5)) / 2 }
abs(x^2 - 4) = 3*x { 1, 4, 4.0000000000000062… + 1.6E-7i } { 1, 4 }

The change: a polynomial keeps one sign between neighbouring real roots. So a modulus of a polynomial with real numeric coefficients takes its real roots as its kinks.

  • The roots come from the analytical solver and are kept exact, so a piece that holds throughout is an exact interval.
  • A polynomial with no real root has no kinks, and the whole line is one piece.
  • Anything else still declines, so nothing that answered before changes.

Checked:

  • ModulusEquationTest has 6 more rows: those above, abs(x^2 - 1) + abs(x - 2) = 3 ({ -1, 0, 2 }), abs(x^2 - 2) = 1, abs(x^2 + 1) = 2, and x^2 + 1 = abs(x) ({ }).
  • Unit suite: 17,164 passed, 0 failed, before the six new rows.
  • RootCheck 596/596 clean; CasBench 120/121, unchanged; BoundCheck 0 disagreements.
  • BREAKING-CHANGES entry added, measured on the 2.6.0 package.

Not in this PR: the complex codomain, which is the issue's own setting, is unchanged. A case split there can miss roots at which the argument is not real: x^2 + 1 = |x| has roots at ±0.618 i, where |x| = 0.618 and x is not ±0.618. And Newton's method in the complex plane assumes a holomorphic function, which |1 - x^2| is not. Which way to go there is asked on #2139.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

…s real roots

With the real codomain, ModulusSolver.SolveOverTheReals solved an
equation in moduli by cases between the kinks, but only where every
modulus was of a linear function. A modulus of anything else fell
through to Newton's method. x^2/|1 - x^2| = x was answered
{ 0, 0.618..., 1.618..., 1.618... + 1.7e-9 i, 1.618... + 9.9e-8 i }, and
|x^2 - 4| = 3x as { 1, 4, 4.000...0062 + 1.6e-7 i }: over the reals, with
entries that are neither real nor roots.

A polynomial keeps one sign between neighbouring real roots, so a modulus
of a polynomial with real numeric coefficients has its real roots for
kinks, found by the analytical solver and kept exact so that a piece that
holds throughout is an exact interval. A polynomial with no real root has
none, and the whole line is one piece. Anything else still declines, so
nothing that answered changes.

On 2.6.0 and on this branch, with the real codomain:
  x^2/abs(1-x^2) = x     decimals + 2 non-roots -> { 0, (-1 + sqrt(5)) / 2, (1 + sqrt(5)) / 2 }
  abs(x^2 - 4) = 3*x     { 1, 4, 4.0...0062 + 1.6e-7 i } -> { 1, 4 }
Unit suite 17,164 passed, 0 failed (before the six new rows); RootCheck
596/596 clean; CasBench 120/121 unchanged; BoundCheck 0 disagreements.

The complex codomain, the issue's own setting, is unchanged: a split
there can miss roots at which the argument is not real, as x^2 + 1 = |x|
has at +-0.618 i.

Part of #2139

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.38462% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.43%. Comparing base (856b3cb) to head (18c8afa).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...Continuous/Solvers/EquationSolver/ModulusSolver.cs 65.38% 3 Missing and 6 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2178      +/-   ##
==========================================
- Coverage   86.45%   86.43%   -0.03%     
==========================================
  Files         295      295              
  Lines       64969    64988      +19     
  Branches    19092    19099       +7     
==========================================
+ Hits        56171    56172       +1     
- Misses       4770     4783      +13     
- Partials     4028     4033       +5     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 87.00% <65.38%> (-0.03%) ⬇️
fsharp 32.97% <ø> (ø)
interactive 40.72% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...Continuous/Solvers/EquationSolver/ModulusSolver.cs 73.68% <65.38%> (-5.27%) ⬇️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Rafael-SOWNet
Rafael-SOWNet merged commit 257f88b into master Oct 27, 2026
35 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in AngouriMath Oct 27, 2026
@Rafael-SOWNet Rafael-SOWNet moved this from In review to Done in AngouriMath Oct 27, 2026
@Rafael-SOWNet
Rafael-SOWNet deleted the a-modulus-of-a-polynomial-is-split-at-its-real-roots branch October 28, 2026 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant