sympy / sympy

A computer algebra system written in pure Python

Home Page:https://sympy.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sympy results are int, not Integer

m-f-h opened this issue · comments

commented

TL;DR: Since sympy.factor(1) returns sympy.Integer(1), it's inconsistent that sympy.divisors(1) (and even sympy.divisors(sympy.Integer(1))) does not return [sympy.Integer(1)], but [int(1)].

I noticed something potentially confusing that should at least be better documented, if not changed:

I was programming a function involving something along the lines of sum(divisor_sigma(n/d)) for d in divisors(n). Instead of a list of a few integers, the result was horribly long and looked like:

[..., divisor_sigma(1.0) + divisor_sigma(3.0) - 3, divisor_sigma(2.0) + divisor_sigma(4.0) - 4, ...]

Obviously, because I should have used integer division // instead of /. But on a second thought, users should have the right to expect that results of sympy functions should be sympy objects, unless told otherwise. If the result of the divisors() function was a list of elements of type sympy.Integer, then the result would have been as expected.

Now I understand well that it could be a big performance hit, in some situations, to always return unconditionally (and consistently) sympy.Integers instead of ints.

So, IMO, the best would be to provide an option to keep the current behaviour if desired (e.g., for performance reasons -- I guess there isn't any other reason?), or (which IMO should be the default -- maybe after some depreciation period), to return sympy objects as result.

If that isn't feasable / desired, then the documentation of the functions that don't return sympy objects should clearly say so (in the documentation of every instance), because IMO it's an inconsistency: For example, sympy.factor(1) returns sympy.Integer(1), so "why" doesn't sympy.divisors(1) (and even sympy.divisors(sympy.Integer(1))) return [sympy.Integer(1)], but [int(1)]? Looking at the documentation (help()) of the two functions, nothing lets guess that it would be that way. [Yes, I know that factorint also returns a dict of int. And I understand that the result of factor() is (in general) a polynomial, even if it may happen to be just an integer. But again, isn't it inconsistent that sympy functions don't return sympy objects in general, unless otherwise mentioned?]

Things could be better documented but some functions are intended to operate with plain Python types rather than symbolic expressions. This is true of most ntheory functions and I don't think they should be changed because they are useful separately from all of sympy's symbolics. Potentially it would have made sense to have separate functions in different modules that handle this differently e.g. like having a divisor_sigma symbolic function in sympy.functions and a corresponding function for plain integers in sympy.ntheory. The flat import design of sympy where everything is imported at top-level makes this difficult though.