From 548cb32bd87a796ec8b43be27d039b1170646d59 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Mon, 2 Nov 2026 19:03:17 +0000 Subject: [PATCH] Provide a root of a raised radical equation with a parameter with being one An equation in a radical is raised to a power, which adds roots, and each root is put back into the equation to be dropped where it fails. With another name in the equation that cannot be decided, and every root of the raised equation was answered: sqrt(x + 1) + a + x = 0 had both roots of its square, and for each a one of them is not a root. At a = -5 they are 3 and 8, and 8 is not a root; at a = 2 neither is. 2.6.0 answered the same. Each is now provided it is one, the equation at that root, so giving the name a value keeps the roots and drops the rest. An equation in x alone is unchanged: its roots are decided where they are put back. Co-Authored-By: Claude Opus 5.5 --- BREAKING-CHANGES.md | 12 +++++++ .../EquationSolver/FractionedPolynoms.cs | 6 ++++ .../ARaisedRootWithAParameterTest.cs | 36 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 Sources/Tests/UnitTests/Algebra/SolveTest/ARaisedRootWithAParameterTest.cs diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index bc87bc009..ea87d41c5 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -234,6 +234,18 @@ the square root the solver takes after solving for `x^2`, where an equation has | `"x^4 - (a^2 + b^2)*x^2 + a^2*b^2 = 0".Solve("x")` | `{ sqrt((a ^ 2 + b ^ 2 - sqrt((-(a ^ 2 + b ^ 2)) ^ 2 - 4 * a ^ 2 * b ^ 2)) / 2), … }` | `{ -b, b, -a, a }` | | `"sin(x)^2 = (a + 1)^2".Solve("x")` | `{ arcsin(sqrt((a + 1) ^ 2)) + 2 * pi * n_1, … }` | `{ arcsin(-a - 1) + 2 * pi * n_1, … }` | +### A root of a raised radical equation with a parameter is provided it is one + +**Silent: a root of an equation in a radical and another name gains the condition that it is a root.** The equation +is raised to a power, which adds roots, and each root is put back into the equation to be dropped where it fails. With +another name left in, that cannot be decided, and every root of the raised equation was answered as a root of the +equation. Each is now provided it is one, so giving the name a value keeps the roots and drops the rest. + +| Input | Was (2.6.0) | Now | +|---|---|---| +| `"sqrt(x + 1) + a + x = 0".ToEntity().Solve("x").Substitute("a", 2).Simplify()` | two roots, neither a root | `{ }` | +| `"sqrt(x + 1) + a + x = 0".ToEntity().Solve("x").Substitute("a", -5).Simplify()` | `{ 3, 8 }`; 8 is not a root | `{ 3 }` | + ### A fractional power is inverted where its values lie **Silent: a root gains the condition under which it is one.** The principal power `z^p` has argument `p arg(z)`, so diff --git a/Sources/AngouriMath/Functions/Continuous/Solvers/EquationSolver/FractionedPolynoms.cs b/Sources/AngouriMath/Functions/Continuous/Solvers/EquationSolver/FractionedPolynoms.cs index 770e7575b..8b6926cd5 100644 --- a/Sources/AngouriMath/Functions/Continuous/Solvers/EquationSolver/FractionedPolynoms.cs +++ b/Sources/AngouriMath/Functions/Continuous/Solvers/EquationSolver/FractionedPolynoms.cs @@ -118,6 +118,12 @@ static bool BasesAreEqual(List<(Entity main, Integer pow)> f1, var finalExpr = MathS.Pow(normalPolynom, intLcm) - mp; dst = (Set)AnalyticalEquationSolver.Solve(finalExpr, x).InnerSimplified; + // Raising adds roots, and each is put back into the equation to be dropped where it + // fails. With another name in the equation that cannot be decided, and every root of the + // raised equation was answered: sqrt(x + 1) + a + x = 0 had both roots of its square, + // and for each a one of them is not a root. Each is now provided it is one. + if (expr.Vars.Count > 1 && dst is Set.FiniteSet candidates) + dst = new Set.FiniteSet(candidates.Select(root => (Entity)root.Provided(expr.Substitute(x, root).EqualTo(Integer.Zero)))); return true; } } diff --git a/Sources/Tests/UnitTests/Algebra/SolveTest/ARaisedRootWithAParameterTest.cs b/Sources/Tests/UnitTests/Algebra/SolveTest/ARaisedRootWithAParameterTest.cs new file mode 100644 index 000000000..9d203d28b --- /dev/null +++ b/Sources/Tests/UnitTests/Algebra/SolveTest/ARaisedRootWithAParameterTest.cs @@ -0,0 +1,36 @@ +// +// Copyright (c) 2019-2026 Angouri. +// AngouriMath is licensed under MIT. +// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md. +// Website: https://am.angouri.org. +// + +using System.Linq; +using AngouriMath; +using AngouriMath.Extensions; +using Xunit; + +namespace AngouriMath.Tests.Algebra +{ + /// + /// An equation in a radical is raised to a power, which adds roots, and each root is put back into the equation to be + /// dropped where it fails. With a parameter left in that cannot be decided, and every root of the raised equation was + /// answered: sqrt(x + 1) + a + x = 0 had both roots of its square, and for each a one of them is not a root. + /// Each is now provided it is one. No issue was filed. + /// + [Trait("Area", "Algebra")] + public sealed class ARaisedRootWithAParameterTest + { + // Each root left once a is given is a root; a = 2 has none, both roots of the square being complex and not roots. + [Theory] + [InlineData("sqrt(x + 1) + a + x = 0", -5, new[] { "3" })] + [InlineData("sqrt(x + 1) + a + x = 0", 0, new[] { "(1 - sqrt(5)) / 2" })] + [InlineData("sqrt(x + 1) + a + x = 0", 2, new string[0])] + [InlineData("x + sqrt(x - a) = 3", 2, new[] { "(7 - sqrt(5)) / 2" })] + public void AreTheRootsOnceTheParameterIsGiven(string equation, int a, string[] expected) + { + var roots = Assert.IsType(equation.ToEntity().Solve("x").Substitute("a", a).Simplify()); + Assert.Equal(expected.Select(root => root.ToEntity().Simplify()).ToHashSet(), roots.ToHashSet()); + } + } +}