Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manual Integrate cannot do (1/cos(x)) dx #26587

Open
mertunsall opened this issue May 10, 2024 · 5 comments
Open

Manual Integrate cannot do (1/cos(x)) dx #26587

mertunsall opened this issue May 10, 2024 · 5 comments

Comments

@mertunsall
Copy link

When I run

import sympy as sp
from sympy.integrals.manualintegrate import integral_steps
x = sp.Symbol('x')
f = 1/sp.cos(x)
integral_steps(f, x)

I get DontKnowRule(integrand=1/cos(x), variable=x) even though this is simple integration of sec(x) which is already handled as this code

import sympy as sp
from sympy.integrals.manualintegrate import integral_steps
x = sp.Symbol('x')
f = sp.sec(x)
integral_steps(f, x).eval()

yield log(tan(x) + sec(x)).

I believe the problem is that the function rewrites_rule in manual integrate does not do what it's supposed to do.

def rewrites_rule(integral):
    integrand, symbol = integral

    if integrand.match(1/cos(symbol)):
        rewritten = integrand.subs(1/cos(symbol), sec(symbol))
        return RewriteRule(integrand, symbol, rewritten, integral_steps(rewritten, symbol))

The condition in this integral gives empty dictionary as there are no Wild variables to be matched so the RewriteRule is never executed. I think the issue can be easily fixed in many ways such as

  1. substituting (1/cos) everywhere without the condition
  2. checking integrand == 1/cos(symbol) directly

Not sure what is the best way to go but after discussion I can do a PR.

Thanks.

@asmeurer
Copy link
Member

I would say the match logic is wrong. It should be checking if integrand.match(1/cos(symbol)) is not None.

Although I wonder if this function should just be deleted. It's called "rewrites_rule" but it just matches this one exact integral (and as noted, it isn't even doing it correctly). There's already other code that tries to substitute 1/cos(x) for sec(x). Why doesn't that work for this integral?

If we want to add a simple integrals table to manualintegrate, that's fine, but we should do so in a more compact format, and ideally that table should include more than just this one single integral.

@mertunsall
Copy link
Author

Yes - I agree with you that even if the function worked properly it does not achieve anything beyond integrating 1/cos(x). I think at the very least it should be renamed.

I think it's probably better to not create a bigger table of integrals as the goal of manualintegrate is to describe the steps on how to do an integral manually by only relying on some very elementary antiderivatives rather than getting the final answer for all cases.

I am not yet too deep into the substitution part of the code but it doesn't seem to work well for similar cases that include these kind of substitutions. For example, it cannot integrate 1/(cos(x) + sec(x)) as well which can be solved by writing this as cos(x)/(1+cos^2(x)) and doing integration by parts. I will try to investigate why this doesn't work.

@asmeurer
Copy link
Member

A table could be useful if it were large enough. However, that's also the goal of the ongoing project to integrate RUBI into SymPy (see https://github.com/sympy/rubi).

@asmeurer
Copy link
Member

And as far as trig integrals go, we'd be better off teaching manualintegrate how to do Weierstrass substitution.

@smichr
Copy link
Member

smichr commented May 20, 2024

Weierstrass is great for proving equalities, too. But here is a ref and an example for when args of the trig functions are the same:

>>> integrand=sin(x)
>>> fu(integrate(integrand.rewrite(tan).subs(tan(x/2),t)*2/(1+t**2)).subs(t,tan(x/2)))
-1-cos(x)

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

No branches or pull requests

3 participants