Reasoning about free_symbols / .has( ) for non-Symbol symbols

62 views
Skip to first unread message

Francesco Bonazzi

unread,
Sep 26, 2017, 2:41:26 PM9/26/17
to sympy
In SymPy we have objects that are not Symbol(s) but should behave like symbols.

Examples: Indexed, MatrixElement, sympy.physics.units.Quantity, RandomSymbol, etc...

There are some issue related, for example:

In [1]: A = IndexedBase("A")

In [2]: Order(A[i])
Out[2]: O(A[i]; (A, i) (0, 0))

In [3]: Order(A[i]).args
Out[3]: (A[i], (A, 0), (i, 0))

In [5]: Order(A[i], A[i]).args
Out[5]: (A[i], (A[i], 0))


I would expect output 3 an output 5 to be the same, but it's not the case. Output 3 is due to the fact that A[i].free_symbols gives {A, i}, therefore Order interprets A[i] as an expression of A and i.

Similar issues appear in the calculations of derivatives, limits, series, equation solvers and so on. It seems that in most cases they trace back to the behaviour of .free_symbols and .has( ), which is well defined for expressions of Symbol, but in case of symbol-like objects could produce the wrong behaviour.

I suggest to create some extra methods, let's say .free_symbols_in_expr and .has_in_expr( ), they should act corresponding to the previous methods, with the exception of stopping the recursion once an expression atom has been reached. For example, A[i] can be put in an expression, but its arguments (A and i) are no subparts of the expression anymore, therefore A[i].free_symbols_in_expr should return {A[i]}.

Order( ... ) could be changed to use these new methods and make output 3 and 5 equivalent.

Aaron Meurer

unread,
Sep 26, 2017, 6:08:07 PM9/26/17
to sy...@googlegroups.com
I like the idea. It makes sense to me that has() should work strictly
symbolically, and that a more mathematically aware version could be
useful. It needs a better name than that, though.

For free_symbols, I'm not so sure. It seems to me that the correct
free_symbols should be {A[i], i}. i is indeed free in the expression.
This is perhaps a bit confusing for Order since it isn't a continuous
variable, but consider something like a summation. summation(expr, (i,
a, b)) equals (b - a + 1)*expr if i is not in the free symbols of
expr, which we obviously don't want of expr contains A[i].

I don't know if it's worth having a separate free_symbols, since
free_symbols is already a mathematically defined concept. The fact
that a summation or integration variable is not free is a mathematical
property, not a property of the expression tree. Could we just make it
so that A[i].free_symbols returns {A[i], i}?

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 https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/c7fb8c69-6d39-44c0-aa99-0f69f537b5d2%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Francesco Bonazzi

unread,
Sep 27, 2017, 5:12:34 PM9/27/17
to sympy


On Tuesday, 26 September 2017 18:08:07 UTC-4, Aaron Meurer wrote:
For free_symbols, I'm not so sure. It seems to me that the correct
free_symbols should be {A[i], i}. i is indeed free in the expression.



This is perhaps a bit confusing for Order since it isn't a continuous
variable, but consider something like a summation.

Now I get:
In [5]: Order(A[i])
Out[5]: O(A[i], A, i, A[i])

I think we need a variation of free_symbols that stops at A[i] without going further into {A, i}.



I don't know if it's worth having a separate free_symbols, since
free_symbols is already a mathematically defined concept.

Well, the question is how to behave in case of composite objects, that is when you reach an object that is itself a free symbol, but contains other free symbols inside of it.

The fact
that a summation or integration variable is not free is a mathematical
property, not a property of the expression tree. Could we just make it
so that A[i].free_symbols returns {A[i], i}?

We need to make it return {A[i], A, i} as A may be an array.

Aaron Meurer

unread,
Sep 27, 2017, 5:41:55 PM9/27/17
to sy...@googlegroups.com
Is there a use-case for the Order expression?

I think it's akin to taking the Order with respect to a function, like
f(x). Does that make sense? We allow it for differentiation under
specific circumstances because it's convenient to treat f(x) as an
atomic variable. Maybe Order should also use _diff_wrt.

On Wed, Sep 27, 2017 at 5:12 PM, Francesco Bonazzi
<franz....@gmail.com> wrote:
>
>
> On Tuesday, 26 September 2017 18:08:07 UTC-4, Aaron Meurer wrote:
>>
>> For free_symbols, I'm not so sure. It seems to me that the correct
>> free_symbols should be {A[i], i}. i is indeed free in the expression.
>
>
> https://github.com/sympy/sympy/pull/13360
>
>>
>> This is perhaps a bit confusing for Order since it isn't a continuous
>> variable, but consider something like a summation.
>
>
> Now I get:
> In [5]: Order(A[i])
> Out[5]: O(A[i], A, i, A[i])
>
> I think we need a variation of free_symbols that stops at A[i] without going
> further into {A, i}.

This seems correct, actually. If you don't provide the variable for
the Order to be with respect to, it guesses automatically, and pulls
in as many possibly varying symbols as possible. The real problem
here, I believe, is that the inclusion of i in the variables seems
wrong because i is not continuous, but this is specific to Order, not
to free_symbols in general.

Won't the more explicit Order(A[i], A[i]) work?

>
>
>>
>> I don't know if it's worth having a separate free_symbols, since
>> free_symbols is already a mathematically defined concept.
>
>
> Well, the question is how to behave in case of composite objects, that is
> when you reach an object that is itself a free symbol, but contains other
> free symbols inside of it.
>
>> The fact
>> that a summation or integration variable is not free is a mathematical
>> property, not a property of the expression tree. Could we just make it
>> so that A[i].free_symbols returns {A[i], i}?
>
>
> We need to make it return {A[i], A, i} as A may be an array.

Can A be a more complicated expression?

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 https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/270865d9-77c5-47fd-b7bf-a0d41cb62a2f%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages