Repository navigation
Add five families of standard integrals (#233) - #675
Merged
Happypig375 merged 3 commits intoAug 4, 2026
Merged
Conversation
Three categories of the integral corpus sat at 0%. None of them needed new machinery; each is a table entry that was missing. k / sqrt(a x^2 + b x + c). An arcsine where a < 0 and a logarithm where a > 0, returned as a piecewise on that sign the way the rational quadratic beside it already is. Nothing integrated 1 / sqrt(1 - x^2) at all before. An exponential times a sine or cosine. Integrating by parts twice returns the integral it started from, so the general solver cycles rather than terminating. Solving that equation for the integral once gives a closed form, and the rate is read off B^(px + q) as p * ln(B), so any base and any linear argument work. The inverse trigonometric functions. Each is integration by parts against 1, and the by-parts solver looks for a product to split, so it never saw them. TestIntegrationByPartsNonPolynomial was skipped with "TODO: integration by parts multiple times". Five of its six cases pass now -- both exponential-times-wave ones and all three inverse trigonometric ones -- so it is no longer skipped. The sixth wants by parts three times over and is split out into its own skipped test rather than holding the rest back. On the 117-problem corpus: 82 -> 88 solved. int:arcsin-form and int:by-parts-cyclic go from 0% to 100%. Every one of the 25 new tests checks by differentiating the answer back at points inside the integrand's own domain -- 1/sqrt(x^2 - 1) is imaginary on (-1, 1), and testing it there would say nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #675 +/- ##
==========================================
- Coverage 80.99% 80.32% -0.68%
==========================================
Files 155 156 +1
Lines 13687 12780 -907
Branches 1957 2088 +131
==========================================
- Hits 11086 10265 -821
+ Misses 1990 1916 -74
+ Partials 611 599 -12 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
sin(x)^3 and sin(x)^2 * cos(x)^2 had no antiderivative; sin(x)^2 and cos(x)^2 each had one written out by hand. There are two cases and this does both. With an odd power there is a factor to peel off as the differential -- sin^(2k+1) = sin * (1 - cos^2)^k -- which leaves a polynomial in the other function, so the integral is a finite sum. With both powers even there is no such factor, so the halved-angle identities go in and the result is integrated again; the total power halves each time, so it ends. That subsumes the two hand-written squares, which are gone. Where both powers are odd either substitution serves and the two answers differ by a constant. The sine one is tried first, because sin(x)cos(x) is written sin(x)^2/2 rather than -cos(x)^2/2, and two existing tests say so. On the corpus: 88 -> 90 solved, int:trig-powers from 50% to 100%. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sqrt(1 - x^2) and sqrt(x^2 + 1) had no antiderivative. Integrating by parts once
leaves the reciprocal form this branch already added, so it is written in terms of
that rather than worked out again:
integral sqrt(Q) = (2ax + b) sqrt(Q) / (4a) + (4ac - b^2)/(8a) * integral 1/sqrt(Q)
Only where the leading coefficient is a number other than zero. With a = 0 this is
the square root of something linear, which the power rule already integrates and
which dividing by a would break; there is a test that it is left alone.
On the corpus: 90 -> 92 solved, int:trig-sub from 0% to 67%. No integral category is
left at 0%. What remains there is 1/(x^2 sqrt(x^2 - 1)), which wants a substitution
rather than a table entry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Towards #233. Three categories
of my integral corpus sat at 0%, and none of them needed new machinery — each is a table
entry that was simply missing.
k / sqrt(a x² + b x + c)Nothing integrated
1 / sqrt(1 - x^2)at all. It is an arcsine wherea < 0and alogarithm where
a > 0, returned as a piecewise on that sign, the way the rationalquadratic beside it in the table already is.
sqrt(a x² + b x + c)sqrt(1 - x^2)andsqrt(x^2 + 1)had no antiderivative either. Integrating by partsonce leaves the reciprocal form above, so it is written in terms of that rather than
worked out again. Only where the leading coefficient is a number other than zero — with
a = 0this is the square root of something linear, which the power rule alreadyintegrates, and there is a test that it is left alone.
An exponential times a sine or cosine
Integrating by parts twice returns the integral it started from, so the general solver
cycles rather than terminating. Solving that equation for the integral once gives a
closed form. The rate is read off
B^(px + q)asp · ln(B), so any base and any linearargument work —
2^x · cos(x)ande^(2x) · sin(3x)as much ase^x · sin(x).The inverse trigonometric functions
Each is integration by parts against
1. The by-parts solver looks for a product tosplit, so it never saw them.
Any whole power of sine times any whole power of cosine
sin(x)^3andsin(x)^2 * cos(x)^2had no antiderivative, andsin(x)^2andcos(x)^2each had one written out by hand. There are two cases and this does both:sin^(2k+1) = sin · (1 - cos²)^k— leaving a polynomial in the other function, so theintegral is a finite sum.
the result is integrated again. The total power halves each time, so it ends.
That subsumes the two hand-written squares, which are gone. Where both powers are odd
either substitution serves and the answers differ by a constant; the sine one is tried
first, because
sin(x)cos(x)is writtensin(x)^2/2rather than the equally correct-cos(x)^2/2, and two existing tests say so.A skipped test that is no longer skipped
TestIntegrationByPartsNonPolynomialcarriedSkip = "TODO: integration by parts multiple times". Five of its six cases pass now — both exponential-times-wave ones and allthree inverse trigonometric ones — so the theory runs. The sixth,
ln|x|^3, wants byparts three times over; it is split into its own skipped test rather than holding the
other five back.
I kept that test's
arctanexpectation working by writing the answer withln(abs(...))rather than
ln(...). The argument1 + x²is positive so theabsis redundant, but itmatches both that expectation and the convention the rest of the table already uses.
Result
On the 117-problem corpus: 82 → 92 solved. Three categories go to 100% --
int:arcsin-formandint:by-parts-cyclicfrom 0%,int:trig-powersfrom 50% --and
int:trig-subfrom 0% to 67%. No integral category is left at 0%. What remainsin trig-sub is
1/(x^2 sqrt(x^2 - 1)), which wants a substitution rather than a tableentry.
Testing
UnitTests3889 passed / 0 failed,FSharpWrapperUnitTests127 passed / 0 failed, bothnetstandard2.0andnet7.0build.43 new tests. Every one checks by differentiating the answer back and comparing at
points, rather than against a printed form — and at points inside each integrand's own
domain:
1/sqrt(x^2 - 1)is imaginary on(-1, 1), so testing it there would saynothing about whether the answer is right. The last group asserts that the neighbouring
table entries are unaffected.
🤖 Generated with Claude Code