Autowrap maintaining symbolic representation?

61 views
Skip to first unread message

Matt Braunstein

unread,
Dec 5, 2019, 8:53:39 PM12/5/19
to sympy
I'm trying to write some symbolic matrices that include complex numbers. But the variables are all real numbers.There are several linear algebra operations performed on these matrices. With just a few of these operations, the size of the matrix explodes beyond being useful to maintain within Python. I'm trying to port these computations to C. However, it seems that the autowrap function creates code that requires numeric values for all variable. I need to maintain the symbolic representation through these computations, because they are then generating optimization goals for model fitting.

I found symengine, which seems to do this and is compatible with Sympy. But their variables are only represented as complex numbers. All my variable are real numbers. Formulating the equations with complex variables results in dramatically more complex computations.

Is there a way to keep symbolic representation, but compute in C with Sympy and autowrap? I thought that creating a custom printer might be a solution, but I'm not sure how to go about writing something to do this. I would appreciate any advice/help on this. Thanks.

Oscar Benjamin

unread,
Dec 7, 2019, 11:45:15 AM12/7/19
to sympy
I don't know about autowrap but there can be improvements to the
handling of symbolic matrices in SymPy. It sounds like you are
referring to expression blowup. There has been some work to improve
that in matrix multiplication and matrix powers:
https://github.com/sympy/sympy/pull/17247

What kind of operation are you doing and what does a typical matrix
look like? If you are talking about expression blowup then the
asymptotic performance of that is so bad that switching to another
language might not help at all.

--
Oscar
> --
> 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/f939319f-474e-4a90-a6d9-3ea11b13fbdd%40googlegroups.com.

Matt Braunstein

unread,
Dec 7, 2019, 3:12:40 PM12/7/19
to sympy
The problem is related to multiple inverse and add operations. This is related to representing a simple linear FET model. Below are the operations that are being performed. I'm having to decompose these to generate equations for use in optimization. There are additional matrix operations beyond these I would like to do as well, but even just the below is too much.

Yint = sympy.matrix([[2/rb + I*w*2*cb, -1/rb - I*w*cb], [-1/rb - I*w*cb, 1/rb + 1/rc +I*w*(cb + cc)]])
Zint = Yint.inv()
Zext = sympy.matrix([[rg + rs + I*w*(lg + ls), rs + I*w*ls],[rs + I*w*ls, rd + rs + I*w*(ld + ls)]])
Z
= Zext + Zint
Y
= Z.inv()
Yre = sympy.re(Y)
Yim = sympy.im(Y)
err
= (Yre_me - Yre)**2 + (Yim_me - Yim)**2

Actually, when manually running these equations in the command line interface for symengine, it completed even quicker than I expected. It took on the order of a couple of seconds to complete. When doing the same completely in python with Sympy, it took on the order of minutes to complete. This was the reason I thought about using autowrap to generate the code in C++. Maybe I'm just trying to fit a square peg in a round hole and need to keep looking for the right tool for the job.

Oscar Benjamin

unread,
Dec 7, 2019, 8:19:28 PM12/7/19
to sympy
These calculations can be made much faster in SymPy. These are only
2x2 matrices so I would just take the basic formula for the inverse of
a 2x2 matrix and sub into that:

In [20]: Matrix([[x, y], [z, t]]).inv()
Out[20]:
⎡ t -y ⎤
⎢───────── ─────────⎥
⎢t⋅x - y⋅z t⋅x - y⋅z⎥
⎢ ⎥
⎢ -z x ⎥
⎢───────── ─────────⎥
⎣t⋅x - y⋅z t⋅x - y⋅z⎦


The denominator can be factored out of the calculation. I expect that
you can make something work in SymPy here in a way that is much easier
than trying to use C/autowrap.

Yes, SymPy should be faster at handling this. I tried your code and I
found that it hung in equals. I think that's a bug that is already
reported:
https://github.com/sympy/sympy/issues/14675

Here's your code (including the necessary symbol definitions - please
include those!):

from sympy import *

rb, rc, rg, rs, rd, w, cb, cc, lg, ld, ls = symbols('rb, rc, rg, rs,
rd, w, cb, cc, lg, ld, ls')

Yint = Matrix([[2/rb + I*w*2*cb, -1/rb - I*w*cb], [-1/rb - I*w*cb,
1/rb + 1/rc +I*w*(cb + cc)]])
Zint = Yint.inv()
Zext = Matrix([[rg + rs + I*w*(lg + ls), rs + I*w*ls],[rs + I*w*ls, rd
+ rs + I*w*(ld + ls)]])
Z = Zext + Zint
Y = Z.inv()
Yre = sympy.re(Y)
Yim = sympy.im(Y)
err = (Yre_me - Yre)**2 + (Yim_me - Yim)**2

--
Oscar
> --
> 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/b081b222-e4f7-40d4-ae7e-ed0e6bacd65b%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages