Unable to solve 2*x*cos(2*x) + sin(2*x)

106 views
Skip to first unread message

Amit Saha

unread,
Jan 13, 2015, 5:14:01 PM1/13/15
to sy...@googlegroups.com
Hi all,

Just ran into this:

>>> from sympy import solve
>>> solve(2*x*cos(2*x) + sin(2*x))
Traceback (most recent call last):
File "<pyshell#65>", line 1, in <module>
solve(2*x*cos(2*x) + sin(2*x))
File "/usr/lib/python3.3/site-packages/sympy-0.7.6_git-py3.3.egg/sympy/solvers/solvers.py",
line 912, in solve
solution = _solve(f[0], *symbols, **flags)
File "/usr/lib/python3.3/site-packages/sympy-0.7.6_git-py3.3.egg/sympy/solvers/solvers.py",
line 1307, in _solve
return _solve(newf, symbol, **flags)
File "/usr/lib/python3.3/site-packages/sympy-0.7.6_git-py3.3.egg/sympy/solvers/solvers.py",
line 1423, in _solve
"\nNo algorithms are implemented to solve equation %s" % f)
NotImplementedError: multiple generators [x, tan(x)]
No algorithms are implemented to solve equation 2*x*(-tan(x)**2 +
1)/(tan(x)**2 + 1) + 2*tan(x)/(tan(x)**2 + 1)

Thanks for any insights into this and whether there is a workaround.

Best,
Amit.


--
http://echorand.me

Ondřej Čertík

unread,
Jan 13, 2015, 5:23:44 PM1/13/15
to sympy
Hi Amit,
What is the solution?

Ondrej

Sergey Kirpichev

unread,
Jan 13, 2015, 5:24:00 PM1/13/15
to sy...@googlegroups.com
On Wednesday, January 14, 2015 at 1:14:01 AM UTC+3, Amit Saha wrote:
Thanks for any insights into this and whether there is a workaround.

What do you expect instead and why?  Not all algebraic equations
have analytic solutions.  Mathematica can't do this eq as well.

Aaron Meurer

unread,
Jan 13, 2015, 5:27:26 PM1/13/15
to sy...@googlegroups.com
I don't think there are analytic solutions. The equation is equivalent to solving tan(x) = -x.

Aaron Meurer

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/2fb262a2-cabd-4cd7-b579-b205b721c8ec%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Amit Saha

unread,
Jan 13, 2015, 5:42:24 PM1/13/15
to sy...@googlegroups.com
On Wed, Jan 14, 2015 at 8:27 AM, Aaron Meurer <asme...@gmail.com> wrote:
> I don't think there are analytic solutions. The equation is equivalent to
> solving tan(x) = -x.
>
> Aaron Meurer
>
> On Tue, Jan 13, 2015 at 4:24 PM, Sergey Kirpichev <skirp...@gmail.com>
> wrote:
>>
>> On Wednesday, January 14, 2015 at 1:14:01 AM UTC+3, Amit Saha wrote:
>>>
>>> Thanks for any insights into this and whether there is a workaround.
>>
>>
>> What do you expect instead and why? Not all algebraic equations
>> have analytic solutions. Mathematica can't do this eq as well.

Thanks for the quick replies all. The Traceback made me wrongly
believe that perhaps sympy is doing something wrong. To be fair to
myself, I was also laid astray by:
http://www.wolframalpha.com/input/?i=solve%282*x*cos%282*x%29+%2B+sin%282*x%29%29

Which gave me an approximate solution - I should have checked myself.

Anyway, thanks all and sorry for the noise.

Aaron Meurer

unread,
Jan 13, 2015, 5:53:32 PM1/13/15
to sy...@googlegroups.com
On Tue, Jan 13, 2015 at 4:41 PM, Amit Saha <amits...@gmail.com> wrote:
On Wed, Jan 14, 2015 at 8:27 AM, Aaron Meurer <asme...@gmail.com> wrote:
> I don't think there are analytic solutions. The equation is equivalent to
> solving tan(x) = -x.
>
> Aaron Meurer
>
> On Tue, Jan 13, 2015 at 4:24 PM, Sergey Kirpichev <skirp...@gmail.com>
> wrote:
>>
>> On Wednesday, January 14, 2015 at 1:14:01 AM UTC+3, Amit Saha wrote:
>>>
>>> Thanks for any insights into this and whether there is a workaround.
>>
>>
>> What do you expect instead and why?  Not all algebraic equations
>> have analytic solutions.  Mathematica can't do this eq as well.

Thanks for the quick replies all. The Traceback made me wrongly
believe that perhaps sympy is doing something wrong. To be fair to
myself, I was also laid astray by:
http://www.wolframalpha.com/input/?i=solve%282*x*cos%282*x%29+%2B+sin%282*x%29%29

You should always check when you get a traceback what the error type is. If it's NotImplementedError, then it just means it isn't implemented. Any other error is likely a bug (or it means you have bad input).

I agree that tracebacks can be confusing. I think ideally solve would return an unevaluated Solve object when it can't find any solutions. Returning [] instead of raising NotImplementedError would probably not be a bad idea either (I seem to remember already doing something like this, but I may be thinking of something else).

Aaron Meurer
 


Which gave me an approximate solution - I should have checked myself.

Anyway, thanks all and sorry for the noise.
--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.

Amit Saha

unread,
Jan 13, 2015, 5:56:41 PM1/13/15
to sy...@googlegroups.com
+1 for returning an empty list object - it's IMO user-friendly - way
friendlier than a Traceback.



>
> Aaron Meurer
>
>>
>>
>>
>> Which gave me an approximate solution - I should have checked myself.
>>
>> Anyway, thanks all and sorry for the noise.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "sympy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to sympy+un...@googlegroups.com.
>> To post to this group, send email to sy...@googlegroups.com.
>> Visit this group at http://groups.google.com/group/sympy.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/sympy/CANODV3%3Dp%2BuOVb3apH2CFqDv4fg2V%3D1vfNUvr-dhia5WrcTZc5g%40mail.gmail.com.
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/CAKgW%3D6JVO1UsCMGcNUB4w%3DPc1tu-k8jaMu86SegGd5OU_FfGCw%40mail.gmail.com.
>
> For more options, visit https://groups.google.com/d/optout.



--
http://echorand.me

Aaron Meurer

unread,
Jan 13, 2015, 6:03:24 PM1/13/15
to sy...@googlegroups.com
This should be an easy thing to do for anyone interested in making their first contribution. Just add a line in solve that catches NotImplementedError and converts it to [], and change all the tests that test raises(NotImplementedError).

Aaron Meurer

Sergey B Kirpichev

unread,
Jan 13, 2015, 6:08:29 PM1/13/15
to sy...@googlegroups.com
On Wed, Jan 14, 2015 at 08:55:59AM +1000, Amit Saha wrote:
> +1 for returning an empty list object - it's IMO user-friendly

It's not friendly, it's broken. No way to distinguish between
"no solutions" and "I can't solve".

Exception - only way to workarround this, but in next solve
(see solveset.py) we should try unevaluated Solve object instead.

Aaron Meurer

unread,
Jan 13, 2015, 6:24:50 PM1/13/15
to sy...@googlegroups.com
On Tue, Jan 13, 2015 at 5:08 PM, Sergey B Kirpichev <skirp...@gmail.com> wrote:
On Wed, Jan 14, 2015 at 08:55:59AM +1000, Amit Saha wrote:
> +1 for returning an empty list object - it's IMO user-friendly

It's not friendly, it's broken.  No way to distinguish between
"no solutions" and "I can't solve".

The current situation doesn't really distinguish that, though. It might give the impression that it does, but that's a false impression. 

Example: solve(cos(x) - x) raises NotImplementedError (it has solutions, but they are not analytic). solve(exp(x)) gives [] (it has no complex solutions). But solve(cos(x)**2 + sin(x)**2 - 1) gives [] (it is an identity, so all x solve it), and solve(floor(x) - 5) gives NotImplementedError (5.1 is a solution; this one is issue 7074)

That's why I suggested a Solve object, which could contain that metadata in a more structured way (like Solve.is_all_solutions which would be True/False/None). But for now, solve() already returns an empty list in some cases, so it might as well always do that.


Exception - only way to workarround this, but in next solve
(see solveset.py) we should try unevaluated Solve object instead.

I agree let's try to do this better in the next iteration of solve().

Aaron Meurer
 

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.

Sergey B Kirpichev

unread,
Jan 13, 2015, 6:29:09 PM1/13/15
to sy...@googlegroups.com
On Tue, Jan 13, 2015 at 05:24:26PM -0600, Aaron Meurer wrote:
> The current situation doesn't really distinguish that, though.

Yes, there are bugs (this inconsistency is solved with solveset).

Chris Smith

unread,
Jan 14, 2015, 1:13:54 AM1/14/15
to sy...@googlegroups.com
You can get approximate solutions using nsolve, e.g.

>>> nsolve(2*x*cos(2*x) + sin(2*x),1)
mpf('1.0143789190552171')

Joachim Durchholz

unread,
Jan 14, 2015, 4:28:51 AM1/14/15
to sy...@googlegroups.com
Am 13.01.2015 um 23:53 schrieb Aaron Meurer:
> Returning [] instead of raising NotImplementedError would probably not be a
> bad idea either

That would be confusable with a "we know that there is no solution" (1)
result.
In this case, we have a "we do not know what solutions exit" (2) result,
which should be represented in a clearly distinguishable fashion (both
on the console output and to other code).
An exception should be a "the software has failed" result (3).

SymPy currently does not distinguish between (2) and (3) and reports
everything as a failure.
One *could* usefully separate the two. That would require an explicit
representation of "we do not know", which would have to generate useful
output. Also, algorithms would need to recognize such ResultUnknown
objects and either throw exceptions or do something more intelligent
(such as trying another subalgorithm). It would require some extensive
modifications to the code, so I don't see that happening quickly.

Aaron Meurer

unread,
Jan 14, 2015, 11:43:15 AM1/14/15
to sy...@googlegroups.com
On Wed, Jan 14, 2015 at 3:28 AM, Joachim Durchholz <j...@durchholz.org> wrote:
Am 13.01.2015 um 23:53 schrieb Aaron Meurer:
Returning [] instead of raising NotImplementedError would probably not be a
bad idea either

That would be confusable with a "we know that there is no solution" (1) result.
In this case, we have a "we do not know what solutions exit" (2) result, which should be represented in a clearly distinguishable fashion (both on the console output and to other code).
An exception should be a "the software has failed" result (3).

SymPy currently does not distinguish between (2) and (3) and reports everything as a failure.

No, SymPy cannot distinguish (1) and (2).  If the software failed you should get an exception that isn't NotImplementedError.
 
One *could* usefully separate the two. That would require an explicit representation of "we do not know", which would have to generate useful output. Also, algorithms would need to recognize such ResultUnknown objects and either throw exceptions or do something more intelligent (such as trying another subalgorithm). It would require some extensive modifications to the code, so I don't see that happening quickly.

Exactly. This was part of Harsh's GSoC project last year. It is possible, at least in some cases, to know that you have all the solutions to an equation (take for example polynomials). But solve() as it exists now doesn't keep track of any of that, and it shouldn't give the impression that it does.

Aaron Meurer



--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscribe@googlegroups.com.

To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.

Amit Saha

unread,
Jan 19, 2015, 4:14:57 PM1/19/15
to sy...@googlegroups.com
On Thu, Jan 15, 2015 at 2:42 AM, Aaron Meurer <asme...@gmail.com> wrote:
>
>
> On Wed, Jan 14, 2015 at 3:28 AM, Joachim Durchholz <j...@durchholz.org> wrote:
>>
>> Am 13.01.2015 um 23:53 schrieb Aaron Meurer:
>>>
>>> Returning [] instead of raising NotImplementedError would probably not be
>>> a
>>> bad idea either
>>
>>
>> That would be confusable with a "we know that there is no solution" (1)
>> result.
>> In this case, we have a "we do not know what solutions exit" (2) result,
>> which should be represented in a clearly distinguishable fashion (both on
>> the console output and to other code).
>> An exception should be a "the software has failed" result (3).
>>
>> SymPy currently does not distinguish between (2) and (3) and reports
>> everything as a failure.
>
>
> No, SymPy cannot distinguish (1) and (2). If the software failed you should
> get an exception that isn't NotImplementedError.

I am of the same opinion too. The first impression that I get when I
see NotImplementedError is that, it is not currently implemented and
thus is probably a limitation of SymPy and not that it is perhaps not
just possible to get the solution/answer.



--
http://echorand.me

Joachim Durchholz

unread,
Jan 19, 2015, 4:25:12 PM1/19/15
to sy...@googlegroups.com
Am 19.01.2015 um 22:14 schrieb Amit Saha:
> I am of the same opinion too. The first impression that I get when I
> see NotImplementedError is that, it is not currently implemented and
> thus is probably a limitation of SymPy and not that it is perhaps not
> just possible to get the solution/answer.

Well, do we give a different error message for those problems that are
unsolvable?
Otherwise, the unsolvable ones are going to always give you
NotImplementedError.

I'm assuming that SymPy does not even attempt to identify unsolvable
problems. If that is indeed true, "unsolvable" is a proper subset of
"not implemented", at least from SymPy's perspective, and SymPy does not
distinguish between the two.

Amit Saha

unread,
Jan 19, 2015, 4:29:06 PM1/19/15
to sy...@googlegroups.com
On Tue, Jan 20, 2015 at 7:25 AM, Joachim Durchholz <j...@durchholz.org> wrote:
> Am 19.01.2015 um 22:14 schrieb Amit Saha:
>>
>> I am of the same opinion too. The first impression that I get when I
>> see NotImplementedError is that, it is not currently implemented and
>> thus is probably a limitation of SymPy and not that it is perhaps not
>> just possible to get the solution/answer.
>
>
> Well, do we give a different error message for those problems that are
> unsolvable?
> Otherwise, the unsolvable ones are going to always give you
> NotImplementedError.

Yes. I liked your idea of having a NoResult exception class.

>
> I'm assuming that SymPy does not even attempt to identify unsolvable
> problems. If that is indeed true, "unsolvable" is a proper subset of "not
> implemented", at least from SymPy's perspective, and SymPy does not
> distinguish between the two.

I am not sure if I would say "unsolveable" is a proper subset of "not
implemented". The former I think is: mathematically, there is no
solution. The latter: SymPy cannot do this currently.


--
http://echorand.me

Joachim Durchholz

unread,
Jan 19, 2015, 4:53:29 PM1/19/15
to sy...@googlegroups.com
Am 19.01.2015 um 22:28 schrieb Amit Saha:
>> I'm assuming that SymPy does not even attempt to identify unsolvable
>> problems. If that is indeed true, "unsolvable" is a proper subset of "not
>> implemented", at least from SymPy's perspective, and SymPy does not
>> distinguish between the two.
>
> I am not sure if I would say "unsolveable" is a proper subset of "not
> implemented".

It is. Determining the set of unsolveable problems is itself an
unsolveable problem.

Full disclosure: It is logically impossible to write an algorithm that
can take arbitrary problem descriptions of whatever formalism you
choose, and always determine whether that problem is solvable.
Any correct algorithm will run into an endless loop for an at least
countably infinite subset of the set of possible problems.
And there is no algorithm for determining that subset (that would allow
constructing an algorithm that would work for all cases, which is a
contradiction for the result that there's no such algorithm).

Proof essentially based on Goedel's incompleteness theorem, so this
applies to all logic systems and algorithms that can handle countable
infinities.

(Computer scientists call this the "halting problem".)
Reply all
Reply to author
Forward
0 new messages