working with the real/imaginary part of a symbolic expression

2,707 views
Skip to first unread message

krastano...@gmail.com

unread,
Jun 9, 2011, 6:31:50 PM6/9/11
to sy...@googlegroups.com
Hi,

Short version of the question: How to take the real/imaginary part of a symbolic expression? Can real(x + I*y) give me "x" with the proper assumptions in place?


Here is the context:
I'm implementing a small gaussian optics module that I am going to need during an internship. Here is my problem.

There is a thing called complex beam parameter that is a complex number whose real part is a certain quantity describing the beam and the imaginary part is another such quantity. The formalism treats them together in this complex number.

I want to have a class with the constructor:

>>>a=Constructor(quantityA, quantityB)
>>>a == quantityA + I*quantityB
True

with the assumptions that quantityA and quantityB are real.

Then I want to have the selectors (@property decorators):

>>>a.quantA
quantityA
>>>q.quantB
quantityB

My idea was just to define quantA as real(a) but as far as what the documentation or Google say there is no function "real" for a general symbolic expression in sympy. I suppose I have missed something. Can I take the real part of a general expression? Can real(x + I*y) give me "x" with the proper assumptions in place?

Regars
Stefan

Aaron Meurer

unread,
Jun 9, 2011, 7:39:18 PM6/9/11
to sy...@googlegroups.com
To assume that x is real, define it like

x = Symbol('x', real=True)

Then you can use the functions re() and im(), or the method
.as_real_imag() to get the real and imaginary parts.

In [1]: x, y = symbols('x y', real=True)

In [2]: (x + I*y).as_real_imag()
Out[2]: (x, y)

In [3]: re(x + I*y)
Out[3]: x

In [4]: im(x + I*y)
Out[4]: y

Aaron Meurer

> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To post to this group, send email to sy...@googlegroups.com.
> To unsubscribe from this group, send email to
> sympy+un...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/sympy?hl=en.
>

krastano...@gmail.com

unread,
Jun 9, 2011, 7:54:14 PM6/9/11
to sy...@googlegroups.com
What about re(1/(x+I*y))? It does not evaluate. Is there a function that I should call before re() so I have something with real denominator?

Mateusz Paprocki

unread,
Jun 9, 2011, 8:00:36 PM6/9/11
to sy...@googlegroups.com
Hi,

On 9 June 2011 16:54, krastano...@gmail.com <krastano...@gmail.com> wrote:
What about re(1/(x+I*y))? It does not evaluate. Is there a function that I should call before re() so I have something with real denominator?


Indeed re() and im() don't work on this expression, but you can use .as_real_imag(), e.g.:

In [1]: f = 1/(x+I*y)

In [2]: f
Out[2]: 
   1   
───────
x + ⅈ⋅y

In [3]: re(f)
Out[3]: 
  ⎛   1   ⎞
re⎜───────⎟
  ⎝x + ⅈ⋅y⎠

In [4]: im(f)
Out[4]: 
  ⎛   1   ⎞
im⎜───────⎟
  ⎝x + ⅈ⋅y⎠

In [5]: f.as_real_imag()
Out[5]: 
⎛           -im(y) + re(x)                        -im(x) - re(y)           ⎞
⎜────────────────────────────────────, ────────────────────────────────────⎟
⎜               2                   2                 2                   2⎟
⎝(im(x) + re(y))  + (-im(y) + re(x))   (im(x) + re(y))  + (-im(y) + re(x)) ⎠

.as_real_imag() calls expand(expr, complex=True) which guarantees to give a + b*I were a, b are real (up to bugs in the implementation). Alternatively you can expand manually and use re() and im() on the result from expand().

Mateusz

Aaron Meurer

unread,
Jun 9, 2011, 8:00:37 PM6/9/11
to sy...@googlegroups.com
So, the way that re() and im() are currently implemented, they do not
do evaluation. You should use .as_real_imag() instead. However, I
think this should change. See
http://code.google.com/p/sympy/issues/detail?id=754#c15.

Aaron Meurer

krastano...@gmail.com

unread,
Jun 9, 2011, 8:01:09 PM6/9/11
to sy...@googlegroups.com
I have found it. For future reference it's complicated_expression.expand(complex=True).

krastano...@gmail.com

unread,
Jun 9, 2011, 8:03:05 PM6/9/11
to sy...@googlegroups.com
Thanks for the details!

Aaron Meurer

unread,
Jun 9, 2011, 8:03:24 PM6/9/11
to sy...@googlegroups.com
Yes, I forgot to mention expand(complex=True). If that issue I linked
to were fixed, then re()/im(), .as_real_imag(), and
expand(complex=True) would all be equivalent (except for their return
types).

Aaron Meurer

Reply all
Reply to author
Forward
0 new messages