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

Add atan2 simplifications to simplify and trigsimp #24391

Open
evbernardes opened this issue Dec 15, 2022 · 2 comments
Open

Add atan2 simplifications to simplify and trigsimp #24391

evbernardes opened this issue Dec 15, 2022 · 2 comments
Labels

Comments

@evbernardes
Copy link
Contributor

evbernardes commented Dec 15, 2022

I'm not familiar with the implementation of trigsimp, so instead of making a PR I'll propose two additions that could be possibly useful (and that aren't performed by any of the available options for the method parameter).

First, an arguably common assumption (that can be useful for symbolic analysis) is that:

$$\operatorname{atan_2}(\sin(\theta), \cos(\theta)) = \theta$$

Which also gives:

$$\operatorname{atan_2}(\cos(\theta), \sin(\theta)) = \pi/2 - \theta$$

For comparison, calling simplify(asin(sin(alpha)), inverse=True) ignores possible set problems and returns alpha, as explained on the docs. This inverse parameter is not available on trigsimp (no internal call to inversecombine), and calling simplify(atan2(sin(alpha), cos(alpha)), inverse=True) does not return alpha as could be expected.

This could be implemented, for example, as:

def simp1(theta):
    if type(theta) is not sp.atan2:
        return theta

    b, a = theta.args

    if type(b) == sp.sin and type(a) == sp.cos and b.args[0] == a.args[0]:
        return a.args[0]
    elif type(b) == sp.cos and type(a) == sp.sin and b.args[0] == a.args[0]:
        return sp.pi/2 - a.args[0]
    else:
        return theta

The following full table of relationships could also be implemented:

$$\begin{cases} \operatorname{atan_2}(\sin(\theta), \cos(\theta)) &= + \theta \\\ \operatorname{atan_2}(-\sin(\theta), \cos(\theta)) &= - \theta \\\ \operatorname{atan_2}(\sin(\theta), -\cos(\theta)) &= +\pi - \theta \\\ \operatorname{atan_2}(-\sin(\theta), -\cos(\theta)) &= -\pi + \theta \end{cases}$$ $$\begin{cases} \operatorname{atan_2}(\cos(\theta), \sin(\theta)) &= \pi/2 - \theta \\\ \operatorname{atan_2}(-\cos(\theta), \sin(\theta)) &= - \pi/2 + \theta \\\ \operatorname{atan_2}(\cos(\theta), -\sin(\theta)) &= \pi/2 + \theta \\\ \operatorname{atan_2}(-\cos(\theta), -\sin(\theta)) &= -\pi/2 - \theta \end{cases}$$

Second, consider the symbolic expression $\theta = \operatorname{atan_{2}}(b, a)$

When $|b| = |a|$, the expression can be simplified to: $\theta = \operatorname{atan_{2}}(\operatorname{sign}(b), \operatorname{sign}(a))$ which has only 4 possible values:

$$\operatorname{atan_{2}}(1, 1) = \pi/4$$ $$\operatorname{atan_{2}}(1, -1) = 3\pi/4$$ $$\operatorname{atan_{2}}(-1, 1) = -\pi/4$$ $$\operatorname{atan_{2}}(-1, -1) = -3\pi/4$$

This can be reduced to the following formula:

$$\operatorname{atan_{2}}(\operatorname{sign}(b), \operatorname{sign}(a)) = \operatorname{sign}(b) \times (2 - \operatorname{sign}(a)) \times \pi/4$$

Which can be implemented, for example, as:

def simp2(theta):
    if type(theta) is not sp.atan2:
        return theta

    b, a = theta.args

    if sp.Abs(a) == sp.Abs(b):
        return sp.sign(b)*(2 - sp.sign(a))*sp.pi/4
    else:
        return theta
@evbernardes evbernardes changed the title Add atan2(b, a) simplifications to sympy.simplify.trigsimp.trigsimp Add atan2 simplifications to simplify and trigsimp Dec 15, 2022
@oscarbenjamin
Copy link
Contributor

For real x I think you can have:

atan2(sin(x), cos(x))) == ((x-pi) % (2*pi) + pi

@evbernardes
Copy link
Contributor Author

For real x I think you can have:

Indeed! I imagine though that a simpler x can be more useful for someone using this kind of simplifications, and it would be consistent with the current effect of inversecombine on trigonometric functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants