Repository navigation
Canonical order: factors such as f[x], Erf[1/x] and E^x are variables of a monomial, as in WMA - #2074
Conversation
… of a monomial, as in WMA On top of #2073. As in WMA 15, every factor of a product counts as a variable of the monomial, not only the symbols: - an expression that is not a symbol, such as f[x] or Erf[1/x], is a variable (GeneralVariable) after all the symbols, ordered as a general expression: a f[x] comes after f[x] and before g[x], and b Cos[x] before a Sin[x]. A general expression on its own is a monomial in itself. - a power with an exponent that is not a number comes after the numeric powers of its base: E^x after E^2 and before F. - a sum, alone or as a factor, sorts right after the largest variable of its largest term: (3 x + 3 x^2) y comes before y^3, and x (a + x) before (a + x)^2. This replaces the infinite exponent of #2073. On 3003 pairs of expressions, Order now differs from WMA 15 on 20 pairs, down from 425 with #2073 and 1152 on master, and no pair that either got right goes wrong. The 40 pairs that #2073 made worse are fixed, and the xfail it added to test_calculus.py is removed. Speed: element_order is kept on the expression with the head and elements it was built from, Sort and Orderless sort with it as a key, and Monomial has a fast path for one variable and a cheap ==. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8d6765c to
a3ad318
Compare
|
Right now, the slow behavior I do not feel is a big problem. First, get it right, and then get it fast. My current belief is that if we get rule matching fixed and we spend The other big wins I believe will be in handling NumericArray as NumPy data (needed in plotting) and expression compilation. So LGTM. In fact, this is a huge help! @mmatera - your thoughts? |
|
One small problem: The
So it would be good to clear |
The elements setter and set_head now clear _element_order_cache, as they clear _cache. The check on head and elements stays, for code that assigns _elements or _head directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Done in 7575db2: both the |
Stacked on #2073: the base is its branch. Once #2073 is merged, this one moves to master. It removes the 40 regressions that #2073 lists, and with them the
xfailthat #2073 added. Part of #2071.In WMA, every factor of a product is a variable of the monomial, not only the symbols. Mathics3 skipped factors such as
f[x]orErf[1/x]when it built the key of a product. This PR counts them, as WMA 15 does:GeneralVariableinkeycomparable.py). These variables come after the symbols and are ordered among themselves as general expressions (head, length, elements). A general expression on its own is a monomial in itself.Sort[{E^x, E, E^2, F, x}]is{E, E^2, E^x, F, x}, andx E^xisE^x x.How much closer to WMA
Orderon the same 3003 pairs as in #2073, compared with WMA 15:No pair that master or #2073 gets right goes wrong. The 20 that remain are cases the WMA rule for which is not clear yet (see #2071):
1 - x,-1 + x,x - y);"s"againstSqrt[2].Also still as before: a power with a numeric base and a symbolic exponent (
2^x), and numeric expressions such as-Sqrt[3]againstSqrt[3].Doctests and tests
Sqrt[2/Pi],1/E^xor a third argument ofRoot, and the order of the terms is the same. Two differ in order and belong to the known cases above (2^Re[z],-Sqrt[3]).test_basic.py,test_algebra.py,test_calculus.py,test_diffeqns.pyandtest_linalg.py. I checked each new output against WMA 15; thetest_linalgeigenvalues match WMA up to parentheses.test_canonical_ordergets 7 more cases; 6 of them fail on Canonical order: sums, symbols from other contexts and coefficients, as in WMA #2073.-n 4 --dist loadfile: 20 failed, intest_tensor.py,test_series.py,test_list.py,test_testing_expressions.pyandtest_latex.py. Each of these files passes on its own; theMax[x]failure, for example, is anx = 3left by another file in the same worker.Speed
With general expressions now monomials, comparisons got deeper. To keep this from slowing things down:
element_orderis kept on the expression, together with the head and elements it was built from, so a changed expression rebuilds it;SortandOrderlesssort withelement_orderas a key, which builds each key once instead of at every comparison;Monomialhas a fast path for a single variable and an==that compares the exponents. A tuple comparison calls==before<, and before this both ran the full comparison.On kimmy, best of 7, master vs this PR:
Sortof 3000f[n, g[k]]Table[f[Mod[7 k, 101], g[k]], {k, 3000}]Plus @@ Table[Sin[k x], {k, 1500}]Total[Table[a[k] x^k, {k, 1500}]]Expand[(1 + a + b + c + x + y)^6]Expand[(a + b + c + d)^8]Times @@ Table[f[k]^k, {k, 1000}]Sortof 3000x^i y^jThe one slowdown left is a bare
Sortof general expressions, 1.7×. Sums and products of such expressions are as fast as before or faster.🤖 Generated with Claude Code