diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index c83cb36be..bbf8384e1 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -371,6 +371,21 @@ is the canonical one: square-free, and without what the answer's own denominator
| `"(a - 1)/(1 - b) - (1 - a)/(b - 1)".Simplify()` | `0 provided not (b - 1) * (1 - b) = 0` | `0 provided not b - 1 = 0` |
| `"(x*y*a*b*c)/(c*b*a*x*x)".Simplify()` | `y / x provided not a * b * c * x = 0` | `y / x provided not a * b * c = 0` |
+### A sine or cosine with no real radical form stays as written
+
+**Silent: `sin(pi/7)`, `cos(2pi/9)` and the other values whose only radical form goes through the complex numbers
+simplify to themselves, where they were nested radicals with cube roots of complex numbers.** That is casus
+irreducibilis: no real radical form exists, and the radical was many times longer than the input. The table's
+entries for the sevenths, ninths and eighteenths are passed over, and their half angles with them. A value with a
+real radical form still takes it ([#2143](https://github.com/asc-community/AngouriMath/issues/2143)).
+
+| Input | Was (2.6.0) | Now |
+|---|---|---|
+| `"sin(pi/7)".ToEntity().Simplify()` | `sqrt((1 - 1/6 * (-1 + ((7 + 21 * sqrt(-3)) / 2) ^ (1/3) + ((7 - 21 * sqrt(-3)) / 2) ^ (1/3))) / 2)` | `sin(pi / 7)` |
+| `"cos(2 pi/9)".ToEntity().Simplify()` | `(((sqrt(-3) - 1) / 2) ^ (1/3) + (-(sqrt(-3) + 1) / 2) ^ (1/3)) / 2` | `cos(2/9 * pi)` |
+| `"sin(pi/18)".ToEntity().Simplify()` | `sqrt((1 - 1/4 * ((4 + 4 * sqrt(-3)) ^ (1/3) + (4 - 4 * sqrt(-3)) ^ (1/3))) / 2)` | `sin(pi / 18)` |
+| `"sin(pi/5)".ToEntity().Simplify()` | `1/4 * sqrt(10 - 2 * sqrt(5))` | `1/4 * sqrt(10 - 2 * sqrt(5))` |
+
### A step function at a jump takes the side its argument arrives from
**Silent: a limit of `floor`, `ceil` or `sgn` whose argument arrives on a jump is answered, where it was left
diff --git a/Sources/.editorconfig b/Sources/.editorconfig
index ddd6649cc..062284068 100644
--- a/Sources/.editorconfig
+++ b/Sources/.editorconfig
@@ -238,6 +238,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Convenience/ArctangentPolesTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n
+[Tests/UnitTests/PatternsTest/CasusIrreducibilisTest.cs]
+file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n
+
[Tests/UnitTests/Algebra/SolveTest/ModulusEquationTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n
diff --git a/Sources/AngouriMath/Functions/Simplification/TrigonometricTableValues.cs b/Sources/AngouriMath/Functions/Simplification/TrigonometricTableValues.cs
index 8b78be55b..492e0e93c 100644
--- a/Sources/AngouriMath/Functions/Simplification/TrigonometricTableValues.cs
+++ b/Sources/AngouriMath/Functions/Simplification/TrigonometricTableValues.cs
@@ -52,7 +52,7 @@ private static bool TryPulling(TrigTable table, Complex arg,
for (var j = begin; j <= end; j++)
{
- if (Number.IsZero(table[j].arg - dArg))
+ if (Number.IsZero(table[j].arg - dArg) && !IsWrittenThroughTheComplexNumbers(table[j].res))
{
res = table[j].res;
return true;
@@ -62,6 +62,20 @@ private static bool TryPulling(TrigTable table, Complex arg,
return false;
}
+ ///
+ /// Whether a value is written through numbers that are not real: i, or a square root
+ /// of a negative number. Every angle here is real, so such a value is a real number whose
+ /// radical form needs the complex numbers, casus irreducibilis, and the function of its angle
+ /// is the shorter answer: cos(2pi/7) is
+ /// (-1 + cbrt((7 + 21 sqrt(-3))/2) + cbrt((7 - 21 sqrt(-3))/2))/6, and no real
+ /// radical form exists. sin(pi/7) simplified to the half-angle of it, many times
+ /// longer than the input. Such an entry is passed over rather than removed, so the closed form
+ /// stays on record. https://github.com/asc-community/AngouriMath/issues/2143
+ ///
+ private static bool IsWrittenThroughTheComplexNumbers(Entity value)
+ => value.Nodes.Any(node => node is Complex and not Real
+ || node is Powf(Real { IsNegative: true }, Rational { ERational.Denominator.IsEven: true }));
+
///
/// Every angle in the tables below is written 2pi/n, so they name nothing at
/// all between 2pi/5 and 2pi/3 -- the whole lower half of the circle
diff --git a/Sources/Tests/UnitTests/Common/TrigonometricTableTest.cs b/Sources/Tests/UnitTests/Common/TrigonometricTableTest.cs
index f71af9e82..d18da10aa 100644
--- a/Sources/Tests/UnitTests/Common/TrigonometricTableTest.cs
+++ b/Sources/Tests/UnitTests/Common/TrigonometricTableTest.cs
@@ -91,8 +91,10 @@ public void EveryExactValueAgreesWithTheCallItReplaces()
// the 1158 calls swept: 581 of them resolved before the half turn was applied
// and 690 after, and the 581 were already sound -- what was missing was missing,
// not wrong. Raise this if the table gains entries; it is here to catch losing
- // them silently.
- Assert.True(resolved >= 690, $"only {resolved} of the swept angles resolved at all");
+ // them silently. 642 since the entries written through the complex numbers, the
+ // sevenths, ninths and eighteenths and the half angles of them, are passed over and
+ // their calls left as written: https://github.com/asc-community/AngouriMath/issues/2143
+ Assert.True(resolved >= 642, $"only {resolved} of the swept angles resolved at all");
}
///
diff --git a/Sources/Tests/UnitTests/PatternsTest/CasusIrreducibilisTest.cs b/Sources/Tests/UnitTests/PatternsTest/CasusIrreducibilisTest.cs
new file mode 100644
index 000000000..b93a4c872
--- /dev/null
+++ b/Sources/Tests/UnitTests/PatternsTest/CasusIrreducibilisTest.cs
@@ -0,0 +1,54 @@
+//
+// 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;
+using static AngouriMath.Entity.Number;
+
+namespace AngouriMath.Tests.PatternsTest
+{
+ ///
+ /// A sine or cosine whose only radical form goes through the complex numbers, casus irreducibilis, stays as the
+ /// function of its angle. sin(pi/7) simplified to sqrt((1 - 1/6 * (-1 + ((7 + 21 * sqrt(-3)) / 2) ^ (1/3) +
+ /// ((7 - 21 * sqrt(-3)) / 2) ^ (1/3))) / 2), many times longer than the input, and no real radical form exists.
+ /// #2143
+ ///
+ [Trait("Area", "PatternsTest")]
+ public sealed class CasusIrreducibilisTest
+ {
+ [Theory]
+ [InlineData("sin(pi/7)")]
+ [InlineData("cos(pi/7)")]
+ [InlineData("cos(2 pi/7)")]
+ [InlineData("sin(4 pi/7)")]
+ [InlineData("sin(pi/9)")]
+ [InlineData("cos(2 pi/9)")]
+ [InlineData("sin(pi/18)")]
+ public void ItStaysAsWritten(string value)
+ {
+ var simplified = value.ToEntity().Simplify();
+ Assert.DoesNotContain(simplified.Nodes, node => node is Complex and not Real || node is Entity.Powf(_, Rational { ERational.Denominator.IsEven: false }));
+ Assert.True(simplified.Nodes.Count() <= value.ToEntity().Nodes.Count() + 2, simplified.Stringize());
+ var difference = (simplified - value.ToEntity()).EvalNumerical();
+ Assert.True(difference.Abs() < 1e-30, $"{simplified} differs from {value} by {difference}");
+ }
+
+ /// A value with a real radical form still takes it.
+ [Theory]
+ [InlineData("sin(pi/5)", "1/4 * sqrt(10 - 2 * sqrt(5))")]
+ [InlineData("sin(pi/3)", "sqrt(3) / 2")]
+ [InlineData("cos(2 pi/5)", "(sqrt(5) - 1) / 4")]
+ public void ARealRadicalIsStillTaken(string value, string expected)
+ => Assert.Equal(expected, value.ToEntity().Simplify().Stringize());
+
+ [Fact]
+ public void TheIdentitiesStillHold()
+ => Assert.Equal(Integer.One, "sin(pi/7)^2 + cos(pi/7)^2".ToEntity().Simplify());
+ }
+}