From 0aa6988b5edf9a0f68cc811ed80bee94e164ef04 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Sun, 9 Aug 2026 13:41:58 +0000 Subject: [PATCH] Give the quantum factorisation a name that does not collide MathS.Quantum.Factorise differed by one letter from Entity.Factorize, which does something else entirely -- algebraic factoring of an expression against tensor factorisation of a quantum state. Both take an Entity and return an Entity, so the name was all that distinguished them. Renaming it to Factorize would have made the spelling uniform and the API worse: two public Factorize methods doing unrelated things. MathS.Quantum already holds the inverse as TensorExpand, so TensorFactorize states the domain and the direction, pairs with its inverse, and ends the collision. The spelling is fixed as a side effect rather than as the point. MathS.Quantum.IsNormalised becomes IsNormalized in the same pass. Auditing the recorded public surface for the rename showed it was still there, and it is public, so 2.0 is equally the last release that can change it. Shipping one British member after two renames made to remove them would have been the wrong outcome. The internal Factorisation class becomes Factorization and its method follows the public one, since it is that member's implementation. AsymptoticSeries has a private Normalised that is deliberately left alone: private names carry no deadline, so there is no reason for a naming change to reach into the limits code. The public surface now has one spelling throughout, and that is checkable rather than asserted -- PublicApi.txt contains no -ise, -ised or -isation member. Its diff for this change is two members out and two in, nothing else. Co-Authored-By: Claude Opus 5 (1M context) --- BREAKING-CHANGES.md | 37 +++++++++++++++--- Sources/AngouriMath/Convenience/MathS.cs | 14 +++---- .../{Factorisation.cs => Factorization.cs} | 8 ++-- .../UnitTests/Algebra/QuantumStateTest.cs | 38 +++++++++---------- Sources/Tests/UnitTests/Common/PublicApi.txt | 4 +- 5 files changed, 64 insertions(+), 37 deletions(-) rename Sources/AngouriMath/Functions/Quantum/{Factorisation.cs => Factorization.cs} (97%) diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index b23a3d5b6..c29b33258 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -53,6 +53,8 @@ read first. | loud | `round(x)`, `min(a, b)`, `max(a, b)`, `gcd(a, b)` | `UnrecognizedFunctionParseException` | the functions | | loud | 28 members deprecated since 1.x | obsolete but present | removed | | loud | `Latexise`, `ILatexiseable`, `entity_latexise` | the British spelling | `Latexize`, `ILatexizeable`, `entity_latexize` | +| loud | `MathS.Quantum.Factorise` | one letter from the unrelated `Entity.Factorize` | `MathS.Quantum.TensorFactorize` | +| loud | `MathS.Quantum.IsNormalised` | the British spelling | `MathS.Quantum.IsNormalized` | | loud | the target frameworks | `net7.0;netstandard2.0` | `netstandard2.0;net8.0;net10.0` | | **silent** | `abs(x) = c` for a negative `c` | a set of non-solutions | the empty set | @@ -144,17 +146,42 @@ forwarding member: this release is the one that removed 28 members that accumula so adding a permanent one here would undo that on the same day. The compiler reports each site, and the fix is mechanical. -`MathS.Quantum.Factorise` keeps its spelling for now. Renaming it to `Factorize` would give the -library two public `Factorize` methods doing unrelated things — expression factoring on `Entity`, -tensor factorisation on a quantum state — which is a worse outcome than the inconsistency. It wants -a distinguishing name rather than a spelling change, and that is not decided here. - **Downstream.** [`CSharpMath.Evaluation`](https://github.com/verybadcat/CSharpMath) reads LaTeX produced here back into an `Entity` and calls this method. It is unaffected until it moves to 2.0, at which point it needs the new name. [#840](https://github.com/asc-community/AngouriMath/issues/840). +### `MathS.Quantum.Factorise` is now `MathS.Quantum.TensorFactorize` + +| | was | is | +|---|---|---| +| the method | `MathS.Quantum.Factorise(Entity)` | `MathS.Quantum.TensorFactorize(Entity)` | + +The old name differed by one letter from `Entity.Factorize`, which does something else entirely — +algebraic factoring of an expression, against tensor factorisation of a quantum state. Both take an +`Entity` and return an `Entity`, so nothing but the name distinguished them, and the name barely +did. + +Renaming it to `Factorize` would have made the spelling uniform and the API worse: two public +`Factorize` methods doing unrelated things. `MathS.Quantum` already holds the inverse operation as +`TensorExpand`, so `TensorFactorize` states the domain and the direction, pairs with its inverse, +and ends the collision. The spelling is fixed as a side effect rather than as the point. + +**What breaks.** Every call to `MathS.Quantum.Factorise`. There is no forwarding member, for the +same reason as above. The compiler reports each site. + +`MathS.Quantum.IsNormalised` is renamed to `IsNormalized` in the same pass. It carries no collision, +only the spelling — but it is a public member, so 2.0 is equally the last release that can change +it, and leaving it would have meant shipping one British member after two renames made expressly to +remove them. + +With these two, the public surface has one spelling throughout. That is checkable rather than +asserted: `PublicApi.txt` is the recorded surface, and it now contains no `-ise`, `-ised` or +`-isation` member. + +[#843](https://github.com/asc-community/AngouriMath/issues/843). + --- ## Parsing diff --git a/Sources/AngouriMath/Convenience/MathS.cs b/Sources/AngouriMath/Convenience/MathS.cs index 7412b1415..3b0b1856c 100644 --- a/Sources/AngouriMath/Convenience/MathS.cs +++ b/Sources/AngouriMath/Convenience/MathS.cs @@ -6867,30 +6867,30 @@ public static Entity Ket(params int[] qubits) /// all, and a product state such as (|0>+|1>)(|0>+|1>), whose /// separability this does not yet detect. /// - public static Entity Factorise(Entity state) - => Functions.Quantum.Factorisation.Factorise(state) ?? state; + public static Entity TensorFactorize(Entity state) + => Functions.Quantum.Factorization.TensorFactorize(state) ?? state; /// /// A product of states over consecutive qubits multiplied back out into a single - /// superposition -- the inverse of Factorise -- or the expression unchanged + /// superposition -- the inverse of TensorFactorize -- or the expression unchanged /// where it is not such a product. /// public static Entity TensorExpand(Entity state) - => Functions.Quantum.Factorisation.TensorExpand(state) ?? state; + => Functions.Quantum.Factorization.TensorExpand(state) ?? state; /// /// Whether the amplitudes square-sum to one, or where that /// cannot be settled -- a symbolic amplitude need not have a decidable modulus. /// - public static bool? IsNormalised(Entity state) - => Functions.Quantum.Factorisation.IsNormalised(state); + public static bool? IsNormalized(Entity state) + => Functions.Quantum.Factorization.IsNormalized(state); /// /// Whether two states differ only by a global phase, which is the difference no /// measurement can see -- or where that cannot be settled. /// public static bool? EqualUpToGlobalPhase(Entity left, Entity right) - => Functions.Quantum.Factorisation.EqualUpToGlobalPhase(left, right); + => Functions.Quantum.Factorization.EqualUpToGlobalPhase(left, right); } /// diff --git a/Sources/AngouriMath/Functions/Quantum/Factorisation.cs b/Sources/AngouriMath/Functions/Quantum/Factorization.cs similarity index 97% rename from Sources/AngouriMath/Functions/Quantum/Factorisation.cs rename to Sources/AngouriMath/Functions/Quantum/Factorization.cs index b5abf5972..50097890d 100644 --- a/Sources/AngouriMath/Functions/Quantum/Factorisation.cs +++ b/Sources/AngouriMath/Functions/Quantum/Factorization.cs @@ -35,13 +35,13 @@ namespace AngouriMath.Functions.Quantum /// is a rank-one test on the amplitudes across a bipartition -- a different algorithm, /// belonging to this file rather than to the spine, and not written yet. /// - internal static class Factorisation + internal static class Factorization { /// /// The state rewritten as a product, or where it is not a state /// or has no qubit in a definite basis state at either end. /// - internal static Entity? Factorise(Entity expr) + internal static Entity? TensorFactorize(Entity expr) { if (QuantumState.TryRead(expr) is not { } state || state.IsEmpty) return null; @@ -76,7 +76,7 @@ internal static class Factorisation /// superposition, or where the expression is not such a product. /// /// - /// The inverse of , and the reason it is here rather than on the + /// The inverse of , and the reason it is here rather than on the /// spine: within one state the qubits are a fixed width and combining two kets overlays /// them, while a *product* of states concatenates their widths. Those are two different /// monoids on the same type, and only the first is what @@ -143,7 +143,7 @@ private static SparseTerms Slice(SparseTerms state, int from, int to) /// the library. Left to Simplify to settle rather than evaluated numerically, /// so 1/sqrt(2) is recognised exactly. /// - internal static bool? IsNormalised(Entity expr) + internal static bool? IsNormalized(Entity expr) { if (QuantumState.TryRead(expr) is not { } state || state.IsEmpty) return null; diff --git a/Sources/Tests/UnitTests/Algebra/QuantumStateTest.cs b/Sources/Tests/UnitTests/Algebra/QuantumStateTest.cs index f387ed2ac..259daaaae 100644 --- a/Sources/Tests/UnitTests/Algebra/QuantumStateTest.cs +++ b/Sources/Tests/UnitTests/Algebra/QuantumStateTest.cs @@ -57,12 +57,12 @@ public void OppositeAmplitudesCancel() => [Theory] [InlineData(true)] - public void TheStandardStatesAreNormalised(bool _) + public void TheStandardStatesAreNormalized(bool _) { - Assert.True(MathS.Quantum.IsNormalised(Bell)); - Assert.True(MathS.Quantum.IsNormalised(Product)); - Assert.True(MathS.Quantum.IsNormalised(Ghz)); - Assert.True(MathS.Quantum.IsNormalised(Ket(0, 1))); + Assert.True(MathS.Quantum.IsNormalized(Bell)); + Assert.True(MathS.Quantum.IsNormalized(Product)); + Assert.True(MathS.Quantum.IsNormalized(Ghz)); + Assert.True(MathS.Quantum.IsNormalized(Ket(0, 1))); } /// @@ -73,23 +73,23 @@ public void TheStandardStatesAreNormalised(bool _) [Fact] public void AnAmplitudeInFrontIsReadTheSameAsADivisor() { - Assert.True(MathS.Quantum.IsNormalised(1 / Sqrt2 * (Ket(0, 0) + Ket(1, 1)))); + Assert.True(MathS.Quantum.IsNormalized(1 / Sqrt2 * (Ket(0, 0) + Ket(1, 1)))); AssertSame(Ket(0) * (Ket(0) + Ket(1)) * 2, - MathS.Quantum.Factorise(2 * (Ket(0, 0) + Ket(0, 1)))); + MathS.Quantum.TensorFactorize(2 * (Ket(0, 0) + Ket(0, 1)))); } [Fact] - public void AnUnnormalisedStateIsNotNormalised() + public void AnUnnormalizedStateIsNotNormalized() { - Assert.False(MathS.Quantum.IsNormalised(Ket(0, 0) + Ket(1, 1))); - Assert.False(MathS.Quantum.IsNormalised(2 * Ket(0))); + Assert.False(MathS.Quantum.IsNormalized(Ket(0, 0) + Ket(1, 1))); + Assert.False(MathS.Quantum.IsNormalized(2 * Ket(0))); } [Fact] public void SomethingThatIsNotAStateHasNoAnswer() { - Assert.Null(MathS.Quantum.IsNormalised("x + 1".ToEntity())); - Assert.Null(MathS.Quantum.IsNormalised("apply(ket, 5)".ToEntity())); + Assert.Null(MathS.Quantum.IsNormalized("x + 1".ToEntity())); + Assert.Null(MathS.Quantum.IsNormalized("apply(ket, 5)".ToEntity())); } // ---- factorisation ---- @@ -102,13 +102,13 @@ public void SomethingThatIsNotAStateHasNoAnswer() [Fact] public void ADefiniteQubitAtEitherEndFactorsOut() { - var factored = MathS.Quantum.Factorise(Ket(0, 0, 1) + Ket(0, 1, 1)); + var factored = MathS.Quantum.TensorFactorize(Ket(0, 0, 1) + Ket(0, 1, 1)); AssertSame(Ket(0) * (Ket(0) + Ket(1)) * Ket(1), factored); } [Fact] public void ADefiniteLeadingQubitFactorsOutAlone() => - AssertSame(Ket(0) * (Ket(0) + Ket(1)) / Sqrt2, MathS.Quantum.Factorise(Product)); + AssertSame(Ket(0) * (Ket(0) + Ket(1)) / Sqrt2, MathS.Quantum.TensorFactorize(Product)); /// /// **Entanglement is the absence of this.** Neither qubit of a Bell state has a @@ -118,8 +118,8 @@ public void ADefiniteLeadingQubitFactorsOutAlone() => [Fact] public void AnEntangledStateDoesNotFactor() { - AssertSame(Bell, MathS.Quantum.Factorise(Bell)); - AssertSame(Ghz, MathS.Quantum.Factorise(Ghz)); + AssertSame(Bell, MathS.Quantum.TensorFactorize(Bell)); + AssertSame(Ghz, MathS.Quantum.TensorFactorize(Ghz)); } /// @@ -132,7 +132,7 @@ public void AnEntangledStateDoesNotFactor() public void SeparabilityWithoutADefiniteQubitIsNotYetDetected() { var uniform = Ket(0, 0) + Ket(0, 1) + Ket(1, 0) + Ket(1, 1); - AssertSame(uniform, MathS.Quantum.Factorise(uniform)); + AssertSame(uniform, MathS.Quantum.TensorFactorize(uniform)); } // ---- round trip ---- @@ -147,7 +147,7 @@ public void SeparabilityWithoutADefiniteQubitIsNotYetDetected() [InlineData("(0,0,1)+(0,1,1)")] [InlineData("(0,0)+(0,1)")] [InlineData("(1,0,0)+(1,0,1)")] - public void ExpandingAFactorisationReturnsTheOriginal(string which) + public void ExpandingATensorFactorizationReturnsTheOriginal(string which) { var original = which switch { @@ -155,7 +155,7 @@ public void ExpandingAFactorisationReturnsTheOriginal(string which) "(0,0)+(0,1)" => Ket(0, 0) + Ket(0, 1), _ => Ket(1, 0, 0) + Ket(1, 0, 1), }; - var roundTripped = MathS.Quantum.TensorExpand(MathS.Quantum.Factorise(original)); + var roundTripped = MathS.Quantum.TensorExpand(MathS.Quantum.TensorFactorize(original)); AssertSame(original, roundTripped); } diff --git a/Sources/Tests/UnitTests/Common/PublicApi.txt b/Sources/Tests/UnitTests/Common/PublicApi.txt index 8b018d2c0..b8f1bc72f 100644 --- a/Sources/Tests/UnitTests/Common/PublicApi.txt +++ b/Sources/Tests/UnitTests/Common/PublicApi.txt @@ -2300,10 +2300,10 @@ AngouriMath.MathS+Numbers.Create(System.Int64) : AngouriMath.Entity+Number+Integ AngouriMath.MathS+Numbers.Create(System.Numerics.Complex) : AngouriMath.Entity+Number+Complex AngouriMath.MathS+Numbers.CreateRational(PeterO.Numbers.EInteger, PeterO.Numbers.EInteger) : AngouriMath.Entity+Number+Rational AngouriMath.MathS+Quantum.EqualUpToGlobalPhase(AngouriMath.Entity, AngouriMath.Entity) : System.Nullable -AngouriMath.MathS+Quantum.Factorise(AngouriMath.Entity) : AngouriMath.Entity -AngouriMath.MathS+Quantum.IsNormalised(AngouriMath.Entity) : System.Nullable +AngouriMath.MathS+Quantum.IsNormalized(AngouriMath.Entity) : System.Nullable AngouriMath.MathS+Quantum.Ket(System.Int32[]) : AngouriMath.Entity AngouriMath.MathS+Quantum.TensorExpand(AngouriMath.Entity) : AngouriMath.Entity +AngouriMath.MathS+Quantum.TensorFactorize(AngouriMath.Entity) : AngouriMath.Entity AngouriMath.MathS+Series.Maclaurin(AngouriMath.Entity, System.Int32, AngouriMath.Entity+Variable[]) : AngouriMath.Entity AngouriMath.MathS+Series.Taylor(AngouriMath.Entity, System.Int32, System.ValueTuple[]) : AngouriMath.Entity AngouriMath.MathS+Series.Taylor(AngouriMath.Entity, System.Int32, System.ValueTuple[]) : AngouriMath.Entity