how to explicit tell a function is real

109 views
Skip to first unread message

chaowen guo

unread,
Feb 13, 2015, 3:18:56 PM2/13/15
to sy...@googlegroups.com
I run the following code in ipython3 notebook:

import sympy
x=sympy.symbols("x",real=True)
f=sympy.symbols("f",cls=sympy.Function,real=True)
sympy.Abs(f(x)).diff(x)

and expect that the answer is just df(x)/dx. However, sympy still treat the function f is a complex function.

So how to tell sympy that f is a real function?

Chaowen GUO

John Peterson

unread,
Feb 24, 2015, 4:44:36 PM2/24/15
to sy...@googlegroups.com
I would also like to know if there's a way to do this...  "real=True" does not seem to have any special meaning for Functions.

Here's an equivalent test case:

#!/usr/bin/env python
from sympy import *
X = Symbol('X', real=True)
f = Function('f', real=True)(X)
g = Function('g', real=True)(X)
print diff (abs(f-g), X)

The output is:

((re(f(X)) - re(g(X)))*(re(Derivative(f(X), X)) - re(Derivative(g(X), X))) + (im(f(X)) - im(g(X)))*(im(Derivative(f(X), X)) - im(Derivative(g(X), X))))/Abs(f(X) - g(X))

Note that a possible workaround is with subs:

print diff (abs(f-g), X).subs([(im(f),0),
                               (im(g),0),
                               (re(f),f),
                               (re(g),g),
                               (re(Derivative(f, X)), Derivative(f, X)),
                               (re(Derivative(g, X)), Derivative(g, X))])

Which prints:

(f(X) - g(X))*(Derivative(f(X), X) - Derivative(g(X), X))/Abs(f(X) - g(X))



Ondřej Čertík

unread,
Feb 24, 2015, 4:55:28 PM2/24/15
to sympy
We have an issue for what diff(abs(x), x) should be:

https://github.com/sympy/sympy/issues/8502

and what you found seems like a bug. SymPy should be able to use the
fact that "f" is real.

Ondrej

John Peterson

unread,
Feb 24, 2015, 5:01:05 PM2/24/15
to sy...@googlegroups.com
Yes, I came across this while searching for solutions to my issue.  Very interesting!

Actually I'm not too concerned about exactly what form of the derivative is used, only that re() and im() don't appear for Functions declared to be real.
 

and what you found seems like a bug. SymPy should be able to use the
fact that "f" is real. 

OK. If you want me to, I can move this over to an issue at GitHub...

 

Aaron Meurer

unread,
Feb 24, 2015, 5:15:03 PM2/24/15
to sy...@googlegroups.com
The problem is that assumptions on Function don't do anything
(https://github.com/sympy/sympy/issues/6494). If you want to create a
Function with assumptions, you'll need to subclass Function
explicitly, like

class f(Function):
is_real = True

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/03c7a2bd-5031-41d3-96e0-5f95aae12ce8%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

John Peterson

unread,
Feb 24, 2015, 5:51:04 PM2/24/15
to sy...@googlegroups.com


On Tuesday, February 24, 2015 at 3:15:03 PM UTC-7, Aaron Meurer wrote:
The problem is that assumptions on Function don't do anything
(https://github.com/sympy/sympy/issues/6494). If you want to create a
Function with assumptions, you'll need to subclass Function
explicitly, like

class f(Function):
    is_real = True

Thanks for pointing out the real issue!  I tried to implement your suggestion, but I'm not a particularly skillful python programmer, so my first attempt at subclassing Function in the way you described didn't work...

Here's the code:

#!/usr/bin/env python
from sympy import *
class real_function(Function):
  is_real=True

X = Symbol('X', real=True)
f = real_function('f')(X)
g = real_function('g')(X)
print diff (abs(f-g), X)

And the error message:

Traceback (most recent call last):
  File "testcase.py", line 10, in <module>
    f = real_function('f')(X)
TypeError: 'real_function' object is not callable


which I don't understand how to fix.

Ondřej Čertík

unread,
Feb 24, 2015, 5:56:25 PM2/24/15
to sympy
Try this:

In [1]: class f(Function):
...: is_real=True
...:

In [2]: class g(Function):
...: is_real=True
...:

In [3]: X = Symbol('X', real=True)

In [4]: diff(abs(f(X)-g(X)), X)
Out[4]:
⎛d d ⎞
⎜──(f(X)) - ──(g(X))⎟⋅sign(f(X) - g(X))
⎝dX dX ⎠


Ondrej

>
> --
> 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/2952c170-688e-4c2d-a61a-3063e7866c0e%40googlegroups.com.

John Peterson

unread,
Feb 24, 2015, 6:11:17 PM2/24/15
to sy...@googlegroups.com


On Tuesday, February 24, 2015 at 3:56:25 PM UTC-7, Ondřej Čertík wrote:
On Tue, Feb 24, 2015 at 3:51 PM, John Peterson <jwpet...@gmail.com> wrote:
>
>

Try this:

In [1]: class f(Function):
   ...:     is_real=True
   ...:

In [2]: class g(Function):
   ...:     is_real=True
   ...:

In [3]: X = Symbol('X', real=True)

In [4]: diff(abs(f(X)-g(X)), X)
Out[4]:
⎛d          d       ⎞
⎜──(f(X)) - ──(g(X))⎟⋅sign(f(X) - g(X))
⎝dX         dX      ⎠

 
Thanks, this works and IMO is cleaner than my previous subs workaround. 

Aaron Meurer

unread,
Feb 24, 2015, 6:31:34 PM2/24/15
to sy...@googlegroups.com
On Tue, Feb 24, 2015 at 4:51 PM, John Peterson <jwpet...@gmail.com> wrote:
>
>
> On Tuesday, February 24, 2015 at 3:15:03 PM UTC-7, Aaron Meurer wrote:
>>
>> The problem is that assumptions on Function don't do anything
>> (https://github.com/sympy/sympy/issues/6494). If you want to create a
>> Function with assumptions, you'll need to subclass Function
>> explicitly, like
>>
>> class f(Function):
>> is_real = True
>
>
> Thanks for pointing out the real issue! I tried to implement your
> suggestion, but I'm not a particularly skillful python programmer, so my
> first attempt at subclassing Function in the way you described didn't
> work...
>
> Here's the code:
>
>> #!/usr/bin/env python
>> from sympy import *
>> class real_function(Function):
>> is_real=True
>> X = Symbol('X', real=True)
>> f = real_function('f')(X)
>> g = real_function('g')(X)
>> print diff (abs(f-g), X)

It would just be real_function(X).

"Function('f')" is (roughly) the same as "class f(Function): pass".
That is, it creates a subclass of Function called f. You will need to
create a new subclass for each function. Clearly, that's not super
easy to do if you want to create them on the fly, which is why we
should fix that issue.

Aaron Meurer

>
>
> And the error message:
>
>> Traceback (most recent call last):
>> File "testcase.py", line 10, in <module>
>> f = real_function('f')(X)
>> TypeError: 'real_function' object is not callable
>
>
> which I don't understand how to fix.
>
> --
> 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/2952c170-688e-4c2d-a61a-3063e7866c0e%40googlegroups.com.

Aaron Meurer

unread,
Feb 24, 2015, 6:33:20 PM2/24/15
to sy...@googlegroups.com
It looks like

f = Function('f')
f.is_real = True

also works, although I wouldn't use it unless you really don't know
the names of the functions you want to create until runtime.

Aaron Meurer

Chris Smith

unread,
Feb 26, 2015, 1:13:48 AM2/26/15
to sy...@googlegroups.com
You could make a function "factory", right?

def rfunc(name):
  rv = Function(name)
  rv.is_real = True
  return rv

>>> f = rfunc('f')
>>> f(var('x')).is_real
True

Chris Smith

unread,
Feb 26, 2015, 10:42:39 PM2/26/15
to sy...@googlegroups.com
See also issue 8760

Aaron Meurer

unread,
Feb 26, 2015, 10:56:14 PM2/26/15
to sy...@googlegroups.com
Beware that Function caches its input, so if you do

f1 = Function('f')
f2 = Function('f')
f1.is_real = True

then f2 will also be real.

Furthermore, if you disable the cache, "f1 is f2" won't be true, but
"f1 == f2" will be true, even if "f1.is_real != f2.is_real".

Aaron Meurer
> https://groups.google.com/d/msgid/sympy/89825575-1c89-448f-99a3-59718beb8117%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages