diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index 5df610f4b..3153b8641 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -247,6 +247,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 d302b5ab6..974a30b0f 100644 --- a/Sources/AngouriMath/Functions/Continuous/Solvers/EquationSolver/FractionedPolynoms.cs +++ b/Sources/AngouriMath/Functions/Continuous/Solvers/EquationSolver/FractionedPolynoms.cs @@ -131,6 +131,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()); + } + } +}