Skip to content

fix(simplify): Collect like factors, and cancel like terms, in sums#2388

Merged
josdejong merged 5 commits into
josdejong:developfrom
gwhitney:simplify_power_sums
Feb 28, 2022
Merged

fix(simplify): Collect like factors, and cancel like terms, in sums#2388
josdejong merged 5 commits into
josdejong:developfrom
gwhitney:simplify_power_sums

Conversation

@gwhitney
Copy link
Copy Markdown
Collaborator

@gwhitney gwhitney commented Jan 15, 2022

Since products like x*(2x+x^2) are usually written out as polynomials
2x^2+x^3, adds rules to be more eager to move factors into sums to
collect like factors. To complement this, adds a rule extracting
negative powers from a sum. Together, these accomplish canceling
a common factor in numerator and denominator:

(a*k + b*k^2)/k^4 -> k^-4*(a*k + b*k^2)
                  -> a*k^-3 + b*k^-2
                  -> k^-3*(a + k*b)
                  -> (a + k*b)/k^3

Resolves #1423.

@josdejong
Copy link
Copy Markdown
Owner

This is a really nice one 😎 , thanks Glen!

I see some unit tests are breaking, probably because I just merged #2394. Can you have a look at that?

@gwhitney
Copy link
Copy Markdown
Collaborator Author

Yes, the changes from #2394 made it necessary to move simplifyConstant later to be sure to be able to collect up al the constants being shed by moving terms around. So this should now be safe to merge. My only concern about it is that it now greatly increases the simplifications that might be done that are not actually valid for all real numbers (basically, canceling things in the denominator can increase the domain of an expression). Would it be good to settle on a plan and resolve #2391 before merging this?

@josdejong
Copy link
Copy Markdown
Owner

Would it be good to settle on a plan and resolve #2391 before merging this?

That sounds good 👍

@gwhitney gwhitney changed the title fix(simplify): Collect like factors, and cancel like terms, in sums WIP fix(simplify): Collect like factors, and cancel like terms, in sums Feb 7, 2022
@gwhitney
Copy link
Copy Markdown
Collaborator Author

gwhitney commented Feb 7, 2022

Added WIP tag, as this will be rebased and modified to take advantage of the new features when #2399 is finalized and merged, so this should not yet be merged.

…sums

  Since polynomials like `x*(2x+x^2)` are usually written out as polynomials
  `2x^2+x^3`, adds rules to be more eager to move factors into sums to
  collect like factors. To complement this, adds a rule extracting
  negative powers from a sum. Together, these accomplish canceling
  a common factor in numerator and denominator:
  (a*k + b*k^2)/k^4 -> k^-4*(a*k + b*k^2) -> a*k^-3 + b*k^-2 -> k^-3*(a + k*b)
  -> (a + k*b)/k^3

  Resolves josdejong#1423.
  This commit should update this PR to be fully compatible with the
  current development mainline. Will remove 'WIP'.
@gwhitney gwhitney force-pushed the simplify_power_sums branch from 4ed6ac7 to b8e7b81 Compare February 16, 2022 23:18
@gwhitney
Copy link
Copy Markdown
Collaborator Author

Updated to use assumption marking from #2399. Should now be good to merge. Removing "WIP" from title.

@gwhitney gwhitney changed the title WIP fix(simplify): Collect like factors, and cancel like terms, in sums fix(simplify): Collect like factors, and cancel like terms, in sums Feb 16, 2022
@joshhansen
Copy link
Copy Markdown

joshhansen commented Feb 22, 2022

Because it's listed as resolving #1423, I expected the following to pass on this branch, but all fail:

  it('factor out common terms', function () {
    simplifyAndCompare('6x / 3x', '2')
    simplifyAndCompare('-28k / -4k', '7')
    simplifyAndCompare('-28 * (k / -4k)', '7')
  })

I keep wondering if, rather than a long list of heuristics, simplification could be implemented in terms of fundamental properties of the various operations. E.g. we know that 1/1 -> 1 because the identity property for division means x/1 -> x, and we know that b + a -> a + b because of the commutative property of addition. And then by performing a search that seeks lower complexity expressions (rather than just iterating the rules until they stop changing anything) perhaps a wider range of expressions could be simplified with simpler code.

It also strikes me that in many ways a binary tree is not an ideal representation for mathematical operations, as it obscures groups which could be commutatively rearranged or regarded as equivalent---so the code must twist itself around the tree structure rather than benefiting maximally from it.

@gwhitney
Copy link
Copy Markdown
Collaborator Author

I'll take a look right away at your examples. As far as your suggestion of searching for lower complexity based on properties like commutativity/distributivity/etc., that proposal is there in the issues and we do intend to follow it up. The difficulty is that there is a combinatorial explosion of possible simplification paths, so such a search must be controlled tightly. The unfortunate fact is that simplification to the least complex form is known under fairly mild assumptions to be intractable (I forget whether NP-hard or even uncomputable, at the moment) so I am afraid there is a significant art to it (just look at the simplify facilities in other CASes) so I suspect we will be eternally stuck with a fair amount of heuristic. That doesn't mean that we can't do a pretty good job -- certainly your examples should simplify -- but I do think there will always be edge cases.

@gwhitney
Copy link
Copy Markdown
Collaborator Author

OK, I have added all three tests as you specified (without any other changes, see the latest commit) and they all pass. Perhaps there was some issue with how you were performing your tests or checking out this branch? Thanks for your investigations!

@josdejong
Copy link
Copy Markdown
Owner

Thanks again Glen, looks good. Merging the PR now.

@josdejong josdejong merged commit 1ca208c into josdejong:develop Feb 28, 2022
@josdejong
Copy link
Copy Markdown
Owner

These fixes are published now in v10.2.0 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggestion: better simplify by factoring out common terms

3 participants