Skip to content

The square root taken after solving for x^2 is exact where it can be - #2173

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
a-square-root-of-a-square-is-taken-when-a-power-is-inverted
Oct 27, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
a-square-root-of-a-square-is-taken-when-a-power-is-inverted

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

The follow-up #2170 recorded under Not in this PR.

The defect: a polynomial whose powers share a factor is solved in x^gcd, and its roots are the gcd-th roots of what that gives. With the factor 2 that is a square root, written sqrt(y) whatever y was. So an equation with no term in x kept the square under the root that #2170 took out of the formula.

The change: x^2 = y is the quadratic x^2 - y = 0. So with the factor 2, each y goes through the same exact root as the formula, and keeps sqrt where it is not a rational number times a square. The parity check in front refuses a y of odd degree in a symbol, such as x^2 = a, before any polynomial is built.

Solve 2.6.0 this PR
x^2 = (a + b)^2 { sqrt((a + b) ^ 2), -sqrt((a + b) ^ 2) } { -a - b, a + b }
x^4 - (a^2 + b^2)*x^2 + a^2*b^2 = 0 { sqrt((a ^ 2 + b ^ 2 - sqrt(…)) / 2), … } { -b, b, -a, a }
sin(x)^2 = (a + 1)^2 { arcsin(sqrt((a + 1) ^ 2)) + 2 * pi * n_1, … } { arcsin(-a - 1) + 2 * pi * n_1, … }
x^2 + (p - q)^2/4 = 0 { sqrt(-(p - q) ^ 2 / 4), … } { -i * (1/2 * p - 1/2 * q), … }

The eigenvalues of [[0, J], [J, 0]] are now J and -J, not ±sqrt(J^2). Eigenvalues is new since 2.6.0, so its test and doc comment are updated, and no released answer changes there.

Checked:

  • 23 equations had every root substituted back at sampled values of the other symbols, with residual 0.
  • SquareDiscriminantTest has four more rows.
  • Unit suite: 17,144 passed, 0 failed.
  • RootCheck: 596/596 clean.
  • CasBench: 120/121 solved, unchanged.
  • The BREAKING-CHANGES entry from A quadratic whose discriminant is a square is answered without the root #2170 has three more rows, measured on the 2.6.0 package.

Not in this PR: the inversion of f(x)^2 = v in InvertNode has the same shape. I found no equation that reaches it, so it is left as it is rather than changed untested.

Part of #2140.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

A polynomial whose powers share a factor is solved in x^gcd, and its roots
are the gcd-th roots of what that gives. With the factor 2 that is a square
root, written sqrt(y) whatever y was, so an equation with no term in x kept
the square under the root that #2170 took out of the formula:
x^2 = (a + b)^2 was { sqrt((a + b)^2), -sqrt((a + b)^2) }.

x^2 = y is the quadratic x^2 - y = 0, so with the factor 2 each y goes
through the same exact root as the formula, and keeps sqrt where it is not
a rational number times a square. The parity check in front refuses a y of
odd degree in a symbol, such as x^2 = a, before any polynomial is built.

On 2.6.0 and on this branch, Solve:
  x^2 = (a + b)^2                        sqrt form -> { -a - b, a + b }
  x^4 - (a^2 + b^2)*x^2 + a^2*b^2 = 0    nested sqrt -> { -b, b, -a, a }
  sin(x)^2 = (a + 1)^2                   arcsin(sqrt((a + 1)^2)) -> arcsin(a + 1)
The eigenvalues of [[0, J], [J, 0]] are J and -J instead of +-sqrt(J^2);
Eigenvalues is new since 2.6.0, so its test and doc comment are updated
and no released answer changes there.

Twenty-three equations had every root substituted back at sampled values
of the other symbols, with residual 0. Unit suite 17,144 passed, 0 failed;
RootCheck 596/596 clean; CasBench 120/121, unchanged.

Part of #2140

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Rafael-SOWNet Rafael-SOWNet added this to the 2.7.0 milestone Oct 27, 2026
@Rafael-SOWNet Rafael-SOWNet moved this from Todo to In review in AngouriMath Oct 27, 2026
@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.42%. Comparing base (6d5d9e3) to head (8cdcd8b).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2173      +/-   ##
==========================================
- Coverage   86.43%   86.42%   -0.02%     
==========================================
  Files         295      295              
  Lines       64881    64886       +5     
  Branches    19084    19084              
==========================================
- Hits        56081    56077       -4     
- Misses       4770     4780      +10     
+ Partials     4030     4029       -1     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 86.99% <100.00%> (-0.02%) ⬇️
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 Δ
...rces/AngouriMath/Core/Entity/Omni/Entity.Matrix.cs 83.12% <ø> (ø)
...tinuous/Solvers/EquationSolver/PolynomialSolver.cs 84.67% <100.00%> (+1.13%) ⬆️

... and 7 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 c937aae 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-square-root-of-a-square-is-taken-when-a-power-is-inverted 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