0

I am looking for a Python solution that takes a string of a linear equation and outputs a vector of the coefficients.

To make things simple for the start, assume I have a set of equations:

  • given in string form
  • each with no more than 4 elements
  • all are linear
  • in all of them x appears only once

then I would like to get a vectorized representation where

  • the first element is the x coefficient
  • other elements are other coefficients in the equation (not evaluated, but as they are), as if they appeared on the other side of the equation as x
  • zeros to complete the 4-d vector

I give here several input-output equations to get a sense of some of the challenges:

  • '2*x+3=2+5' => [2, -3, 2, 5]
  • '88/8=x' => [8, 88, 0, 0]
  • '74=(35+18)+3*x' => [3, 74, -35, -18]
  • '((4+4)*6)=x'] => [1/6, 4, 4, 0]
  • '-X=(91.0+88.0)' => [-1, 91, 88, 0]
  • 'X=(30.0/10.0)' => [10, 30, 0, 0]
  • '0.16 + 0.41 = 2*x - 0.08' => [2, 0.16, 0.41, 0.08]
  • '(0.25 + 0.37)*2 = x' => [1/2, 0.25, 0.37, 0]

I started coding a "brute force" solution that is highly rigorous and tedious, stumbled several times along the way, and figured there must be a nicer and more clever way to do this...

  • I am using the sympy package, which makes things a bit easier. With sympify and formula.split and such I am able to extract the x coefficient and the result of the equation (although I really don't care about the result, but only the vector representation)
  • I saw this and this but they are both in different languages, and not quite what I am looking for.

Sooo, anyone has any idea how to do it in Python?

Thanks! :)

Community
  • 1
  • 1
DalyaG
  • 2,979
  • 2
  • 16
  • 19

1 Answers1

1

This may get you going in the right direction:

>>> def peq(s):
...     from sympy import S
...     l, r = t = S(s, evaluate=False)
...     free = t.free_symbols
...     assert len(free) == 1
...     x = free.pop()
...     if r.has(x):
...         l, r = r, l
...     assert not r.has(x)
...     assert l.has(x)
...     assert not l.diff(x).free_symbols
...     v = []
...     v.append(l.coeff(x))
...     v.append(-(l.subs(x, 0)))
...     if not r.is_Add:
...         v.extend([r, S.Zero])
...     else:
...         assert r.is_Add and len(r.args) == 2
...         v.extend(r.args)
...     return v
>>> peq('2*x+3,-2+5/3')
[2,−3,−2,5/3]
>>> peq('2*x+3,-2')
[2,−3,−2,0]
>>> peq('x,-2')
[1,0,−2,0]
smichr
  • 16,948
  • 2
  • 27
  • 34
  • Looks great, yet I don't understand what is `S`, and also, is `x` supposed to be `'x'`?. Thanks! – DalyaG Jun 20 '17 at 06:56
  • `S` is the shorthand for the `sympify` function that turns a string into SymPy objects. I'll try to update the function. – smichr Jun 20 '17 at 12:24
  • OK, you might want to test that 'x' actually appears; what I have above will work with anything that looks like a variable, e.g. `y` or `the_variable`. – smichr Jun 20 '17 at 12:29
  • Had to make a couple of semantic changes to make it work, but this is definitely along the lines of what I was looking for. Thanks! – DalyaG Jun 21 '17 at 07:11