Real and Imaginary part of a function

37 views
Skip to first unread message

Lorenzo Monacelli

unread,
Feb 28, 2020, 2:00:50 PM2/28/20
to sympy
Dear all,
I have a complex expression and I want to separate imaginary and real part, however I noticed that when I have derivatives on a function, the real and imaginary part separation does not work properly:

t = sy.Symbol("t", real = True)
f = sy.Function("f", real = True)(t)

 Then if I ask sympy the imaginary part of f, it correctly returns 0, however if I ask the immaginary part of the derivative of f, it is not able to see that it is zero:

sy.im(f) # this is zero (ok!)
sy.im(sy.diff(f, t))  # does not simplify to zero

How can I force sympy to set automatically the derivative of f to real numbers?
Thanks in advance for the help,
Bests, 
Lorenzo

Aaron Meurer

unread,
Feb 28, 2020, 2:02:51 PM2/28/20
to sympy
There is an open issue about this https://github.com/sympy/sympy/issues/11868.

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 view this discussion on the web visit https://groups.google.com/d/msgid/sympy/dec5a368-f065-4a1f-b5da-9bb2b4f74559%40googlegroups.com.

Lorenzo Monacelli

unread,
Feb 29, 2020, 6:20:03 AM2/29/20
to sympy
I have found a simple workaround for this problem. I implemented a function that performs a hardcore substitution of the expression:

def parse_imaginary_real(expression):
    """
    It takes an expression and parse correctly the imaginary and real part of first derivatives of a 
    real or imaginary function.
    
    This function works only for first derivatives. 
    It could be extended easily to work with second or higher order derivatives as well.
    
    """
    all_variables = globals()
    
    # Get the variables that are functions
    all_functions = [x for x in all_variables.values() if isinstance(x, sy.Function)]
    
    new_exp = expression
    for f in all_functions:
        if f.is_real:
            new_exp = expression.subs(sy.im(sy.diff(f)), 0).subs(sy.re(sy.diff(f)), sy.diff(f))
        elif f.is_imaginary:
            new_exp = expression.subs(sy.im(sy.diff(f)), sy.diff(f)).subs(sy.re(sy.diff(f)), 0)
    
    return new_exp


This function can be used as simplify to an expression. Indeed, it has still some issues: it does not check the type of the argument, and it simplifies only first derivatives (and I think it could be very slow if many variables have been defined, I do not know very well how the globals() can work if the function is used on a library).

However, for my simple case, it does the job and allows me to go over, simplifying the imaginary and real parts of first derivatives that are zero by definition. I hope it can be useful for other users.
Bests,
Lorenzo

Il giorno venerdì 28 febbraio 2020 20:02:51 UTC+1, Aaron Meurer ha scritto:
There is an open issue about this https://github.com/sympy/sympy/issues/11868.

Aaron Meurer

On Fri, Feb 28, 2020 at 12:00 PM Lorenzo Monacelli
<lorenzo92...@gmail.com> wrote:
>
> Dear all,
> I have a complex expression and I want to separate imaginary and real part, however I noticed that when I have derivatives on a function, the real and imaginary part separation does not work properly:
>
> t = sy.Symbol("t", real = True)
> f = sy.Function("f", real = True)(t)
>
>  Then if I ask sympy the imaginary part of f, it correctly returns 0, however if I ask the immaginary part of the derivative of f, it is not able to see that it is zero:
>
> sy.im(f) # this is zero (ok!)
> sy.im(sy.diff(f, t))  # does not simplify to zero
>
> How can I force sympy to set automatically the derivative of f to real numbers?
> Thanks in advance for the help,
> Bests,
> Lorenzo
>
> --
> 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 sy...@googlegroups.com.

Lorenzo Monacelli

unread,
Feb 29, 2020, 6:31:18 AM2/29/20
to sympy
The code needs a small edit to work properly with many functions (it requires sympy imported as sy):

def parse_imaginary_real(expression):
    """
    It takes an expression and parse correctly the imaginary and real part of first derivatives of a 
    real or imaginary function.
    
    This function works only for first derivatives. 
    It could be extended easily to work with second or higher order derivatives as well.
    
    """
    all_variables = globals()
    
    # Get the variables that are functions
    all_functions = [x for x in all_variables.values() if isinstance(x, sy.Function)]
    
    new_exp = expression
    for f in all_functions:
        if f.is_real:
            new_exp = new_exp.subs(sy.im(sy.diff(f)), 0).subs(sy.re(sy.diff(f)), sy.diff(f))
        elif f.is_imaginary:
            new_exp = new_exp.subs(sy.im(sy.diff(f)), sy.diff(f)).subs(sy.re(sy.diff(f)), 0)
    
    return new_exp
Reply all
Reply to author
Forward
0 new messages