Substitution in polynomials

40 views
Skip to first unread message

christi...@googlemail.com

unread,
Nov 4, 2007, 1:46:40 PM11/4/07
to sympy
Hi there! :-)

First thank you very much for your work on sympy it is a really
usefull program.

I want to substitute variables in a polynomial, something similar
to what is possible with matrices:
---
>>> M
x 0 0
0 x 0
0 0 x
>>> M.subs(x, 4)
4 0 0
0 4 0
0 0 4
---

Suppose you have a polynomial q(x,y,z) and i want to substitute the
x,y,z
with other expressions, namely other polynomials. Suppose all used
variables
are already declared as symbols.
q = xy + y**2 + zx
x = x1 + x2**2
y = y1 + y3
z = z2*z3
now i want q to become
q = (x1 + x2**2)*(y1 + y3) + (y1 + y3)**2 + (x1 + x2**2)*(z2*z3)
I know i can achive this by declairing x,y,z first but that is not
possible
in this case.

How can I do it? :)

Thank you very much and greetings
Christian Brumm

Ondrej Certik

unread,
Nov 4, 2007, 2:00:13 PM11/4/07
to sy...@googlegroups.com
Hi Christian,

> First thank you very much for your work on sympy it is a really
> usefull program.

Nice to hear that. :)

How about this:

In [1]: q=x*y+y**2+z*x

In [2]: q
Out[2]:
2
y + x*y + x*z

In [3]: x1, x2, y1, y3, z2, z3 = symbols("abcdef")

In [4]: x1, x2, y1, y3, z2, z3
Out[4]: (a, b, c, d, e, f)

In [5]: x0 = x1+x2**2

In [6]: y0 = y1+y3

In [7]: z0 = z2*z3

In [8]: q.subs(x, x0).subs(y, y0).subs(z, z0)
Out[8]:
2 ⎛ 2⎞ ⎛ 2⎞
(c + d) + ⎝a + b ⎠*(c + d) + e*f*⎝a + b ⎠

Does it solve the problem? Or are you looking for something else?

Ondrej

Fredrik Johansson

unread,
Nov 4, 2007, 2:08:06 PM11/4/07
to sy...@googlegroups.com
On 11/4/07, christi...@googlemail.com

Hi Christian,

You have to be careful to distinguish between Python variables and
SymPy symbols.

I would suggest naming the expressions

x_ = x1 + x2**2
y_ = y1 + y3
z_ = z2*z3

and doing

q.subs(x, x_).subs(y, y_).subs(z, z_).

Alternatively, you could do it like this:

x = x1 + x2**2
y = y1 + y3
z = z2*z3

x_ = Symbol('x')
y_ = Symbol('y')
z_ = Symbol('z')

q.subs(x_, x).subs(y_, y).subs(z_, z)

but I think it's generally better to name the variable referring to a
symbol exactly the same thing as the symbol.

This is a rather subtle issue in SymPy and we probably need more
documentation about it.

Fredrik

christi...@googlemail.com

unread,
Nov 5, 2007, 6:23:16 AM11/5/07
to sympy
Hallo Ondrej & Fredrik, thanks a lot for your answers.

Fredrik was right, i was a bit confused with variables and symbols.
subs() worked fine for me with a new set of symbols.

However things start to get messy when you need hundreds of variables
and polynomials.

For example if you want to initalize variables x1 ... x100 (with
symbols),
i did it with the following rather "dirty" and ineffizient code
(i guess exec causes the process to fork?):
---
vars = ['x'+str(i) for i in range(1,101)]
for i, value in enumerate(vars):
exec("x%d = Symbol(value)" %(i+1))
---

I used code similar to the above to perform substitutions on hundreds
of
variables, but all becomes pretty messy and unreadable. (I want to
implement
a cryptosystem that relies on multivariate polynomials.)

Is there a better way to handle these larger scales? Or do I need
something
like Maple or Mathematica here? I would really love to do it in Python

Greeting,
Christian

On 4 Nov., 20:08, "Fredrik Johansson" <fredrik.johans...@gmail.com>
wrote:
> On 11/4/07, christian.br...@googlemail.com

basti

unread,
Nov 5, 2007, 6:41:08 AM11/5/07
to sympy

> For example if you want to initalize variables x1 ... x100 (with
> symbols),
> i did it with the following rather "dirty" and ineffizient code
> (i guess exec causes the process to fork?):
> ---
> vars = ['x'+str(i) for i in range(1,101)]
> for i, value in enumerate(vars):
> exec("x%d = Symbol(value)" %(i+1))
> ---

why you don't just use:
vars = (Symbol('x'+str(i) for i in range(1,101))

you then con access them easiely through vars[i]

basti

Fredrik Johansson

unread,
Nov 5, 2007, 6:42:24 AM11/5/07
to sy...@googlegroups.com
On 11/5/07, christi...@googlemail.com

<christi...@googlemail.com> wrote:
>
> Hallo Ondrej & Fredrik, thanks a lot for your answers.
>
> Fredrik was right, i was a bit confused with variables and symbols.
> subs() worked fine for me with a new set of symbols.
>
> However things start to get messy when you need hundreds of variables
> and polynomials.
>
> For example if you want to initalize variables x1 ... x100 (with
> symbols),
> i did it with the following rather "dirty" and ineffizient code
> (i guess exec causes the process to fork?):
> ---
> vars = ['x'+str(i) for i in range(1,101)]
> for i, value in enumerate(vars):
> exec("x%d = Symbol(value)" %(i+1))
> ---
>
> I used code similar to the above to perform substitutions on hundreds
> of
> variables, but all becomes pretty messy and unreadable. (I want to
> implement
> a cryptosystem that relies on multivariate polynomials.)
>
> Is there a better way to handle these larger scales? Or do I need
> something
> like Maple or Mathematica here? I would really love to do it in Python

Why do you need separate named variables? It seems natural to index
the symbols in a list or dict:

x = dict([(i, Symbol('x' + str(i))) for i in range(1, 101)])

gives

x[1] --> Symbol('x1')
x[2] --> Symbol('x2')

etc.

By the way, the exec statement just compiles and interprets the given
code like an ordinary statement. As far as I know, it does not fork
the process.

Fredrik

christi...@googlemail.com

unread,
Nov 6, 2007, 3:28:49 AM11/6/07
to sympy
Thanks for your answers, a list or dict is much more appropriate here,
I do not know what I was thinking.

Greetings
Christian

On Nov 5, 12:42 pm, "Fredrik Johansson" <fredrik.johans...@gmail.com>
wrote:
> On 11/5/07, christian.br...@googlemail.com

Reply all
Reply to author
Forward
0 new messages