Repository navigation
Put a difference of two divergent fractions over one denominator - #699
Rafael-SOWNet merged 3 commits into
Conversation
Nothing in the descent takes a difference apart any further than asking what each half tends to, so 1/x - 1/sin(x) at 0 came out as +oo - +oo on the right and -oo - -oo on the left, and NaN either way -- the claim that the limit does not exist, where it is 0. Written over the common denominator the same expression is (sin(x) - x) / (x * sin(x)), an ordinary 0/0 that l'Hopital's rule settles in three steps. The rewrite goes where the products already went. AsQuotient existed to hand the rule the quotients that are not written as one, and a sum of fractions is the second kind of those; it is now the one place that answers what the numerator and the denominator of an expression are, for a product and for a sum of them alike. Only where a denominator contains the variable, since it is the denominators that vanish or diverge that make the difference indeterminate, and combining over a constant gains nothing while still costing the rule an expression to differentiate. Only up to three terms: each one multiplies the numerator by every other term's denominator, so the expression grows with the square of the count, and two or three is what the forms that need this are written with. Answers 1/x - 1/sin(x) and 1/sin(x) - 1/x at 0, csc(x) - cotan(x) at 0, and 1/ln(x) - 1/(x - 1) at 1 either way round. Five of the eleven new tests fail without it. Corpus unchanged at 101/117 with 0 wrong; suite 4020 passed, 0 failed.
|
Fork CI, matrix run 30934551606 — success on windows-latest, ubuntu-latest and macos-latest, The branch One note on the interaction with #697: this rewrite changes how the expression is written, not what is being asked of it, so it is as true one side at a time as it is of both. Whether a one-sided limit reaches l'Hopital's rule at all is #697's business, though, so on this branch alone
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #699 +/- ##
==========================================
+ Coverage 80.99% 81.60% +0.60%
==========================================
Files 155 157 +2
Lines 13687 13370 -317
Branches 1957 2207 +250
==========================================
- Hits 11086 10910 -176
+ Misses 1990 1853 -137
+ Partials 611 607 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
tan(x) is opaque to everything that reads quotients: it is neither a quotient nor a negative power, so the split puts it into the numerator whole and 1/x - 1/tan(x) comes out over x * tan(x). That is the right answer written in the wrong form. The rules do reach 0 through it, but only after rewriting the whole expression dozens of ways, and lim x->0+ (1/sin(x) - 1/tan(x)) took forty seconds against under one for the same limit over sin(x) * sin(x). Not with the other trigonometric rewrite, which runs in front of the first remarkable limit. That one matches a quotient, and rewriting tan(b*x - x) as a quotient of its own turns the quotient it sits under into a product: lim x->0 sin(x - a*x) / tan(b*x - x), which the suite pins at (a-1)/(1-b), stops being read at all. Measured, not reasoned about -- it is what the test caught when the rewrite was put there first. Suite 4020 passed, 0 failed, unchanged.
|
Follow-up commit The finding. Each of #697, #699 and #700 is fast on its own. Combined, three limits of this family became very slow — The cause, measured rather than guessed. I instrumented all three mechanisms before changing anything, and my first guess was wrong: #700's derivative-taking accounts for 4 ms of the thirty seconds, and Gruntz for 5. What costs is that So the follow-up writes a tangent and a cotangent as the quotients they are, once, in the limit pipeline. Where it goes matters, and a test caught me putting it in the wrong place. My first attempt added it to
What I have not fixed. The last two are still slow with all three branches applied. Both terminate; Fork CI on the new head, matrix run 30942267526 — success on windows-latest, ubuntu-latest and macos-latest, One correction to my earlier comment: this branch now touches |
The tangent rewrite moves into the block of pre-passes #697 hoisted above the side dispatch, which is where it belonged once that landed. The per-term copy of the same rewrite inside AsQuotient goes: the pass in front of the descent already reaches every term, so keeping both said the same thing twice.
lim x -> 0 (1/x - 1/sin(x))answers NaN. It is 0.Nothing in the descent takes a difference apart any further than asking what each half tends to, and each half here is an infinity: the difference is
+oo - +ooon the right and-oo - -ooon the left. NaN is not "I could not tell" — it is the claim that the limit does not exist.Written over the common denominator the same expression is
(sin(x) - x) / (x * sin(x)), an ordinary 0/0 that l'Hopital's rule settles in three steps.Where the change goes
AsQuotientalready existed for exactly this: it hands the rule the quotients that are not written as quotients, which is whylim x -> +oo x^4 * e^(-x)works (#596). A sum of fractions is the second kind of those, so it goes in the same place —AsQuotientis now the one answer to "what are the numerator and the denominator of this", for a product and for a sum of them alike.Two guards, both to keep the rule from being handed work it cannot use:
What it answers
1/x - 1/sin(x)at 01/sin(x) - 1/xat 0csc(x) - cotan(x)at 01/ln(x) - 1/(x - 1)at 11/(x - 1) - 1/ln(x)at 1Five of the eleven new tests fail without the change.
Not everything in the family lands.
1/x - 1/tan(x)and1/x^2 - 1/sin(x)^2are still NaN, but the rewrite is not what is stopping them:(tan(x) - x) / (x * tan(x))written out by hand is NaN too, so the limitation is further down in what the rule can push a quotient through. Worth its own look, not this PR's.Measurements
Failed: 0, Passed: 4020, Skipped: 14, Total: 4034.Independent of my other open PRs. It touches
AsQuotientinTransformations.cs, which #697 also touches, but in a different part of the file —git merge-treereports no conflict between them.Fork CI to follow in a comment.