how do i solve for an unknown variable without transposing.

112 views
Skip to first unread message

phneoix

unread,
Apr 23, 2012, 12:56:41 AM4/23/12
to sympy
hi,
i have been using spreadsheet for modelling of mathematical
problems. is it possible to use sympy for the same.
eg.

T=f*d

T=100
f=?
d=10
.


i can use goalseek function in spreadsheet to find the value of 'f'.
can i use sympy for the same sort of problems without having to
transpose the equation.

thanks..

Chris Smith

unread,
Apr 23, 2012, 1:55:29 AM4/23/12
to sy...@googlegroups.com

Yes, with a couple of caveats:

1) you have to remember that if you define something then it's no
longer a symbol that you can solve for:

>>> from sympy.abc import x, y
>>> x = 2
>>> Eq(y, x)
y == 2

2) You can't enter equations like above, but should use the Eq()
function to set up equalities. So for your question it might look like
this:

>>> T=100
>>> d=10
>>> solve(Eq(T, f*d), f)
[10]

3) If you want to solve for a variety of variables using the same
equation then an idiom like this might work:

>>> var('f T d') # another way to make (or re-make) the variables
(f, T, d)
>>> eq = Eq(T , f*d)
>>> eq
T == d*f
>>> solve(eq.subs(dict(T=100,d=10)))
[10]

Let's look at that a step at a time.

dict() creates a dictionary of the items given. Note that the keys are strings.
>>> dict(T=100,d=10)
{'d': 10, 'T': 100}

This hasn't assigned a value to T or d in your workspace. When you feed
this dictionary to subs, however, it converts the strings to sympy expressions
which, in this case, are symbols and then does the replacement in you
symbolic equation:

>>> eq.subs(dict(T=100,d=10))
100 == 10*f

Solve then, if you don't tell it what to solve for just solves for a
missing symbol
since there is only one in this case, the solution you got was for f

>>> solve(_)
[10]

sympy is a library that provides tools to help you; python allows you to make
your own tools; since sympy is written in python the two work well together :-)
So if you wanted to have a tool that would take the input like you gave and just
tell you the answer it might look like this:


def ssolve(s, *v):
"""
Solve lines of equations as a set of equations:
>>> from sympy.my import ssolve
>>> ssolve('''
... y=x+3
... x+y=4''')
{x: 1/2, y: 7/2}

Any line containing an '?' will be ignored.

>>> ssolve('''
... y=x+3
... y=4
... x=?''')
{x: 1, y: 4}
"""
from sympy import Eq, solve, Tuple
eq=[]
for li in [si for si in s.strip().splitlines() if si]:
li.replace('==','=')
if '?' in li: continue
if '=' in li: eq.append(Eq(*[S(p) for p in li.split('=')]))
else: eq.append(S(li))
return solve(eq, *(v or list(Tuple(*eq).free_symbols)))

Hope that helps, and welcome to SymPy,
Chris

phneoix

unread,
Apr 29, 2012, 6:03:38 AM4/29/12
to sympy
Thanks,
couldn't reply due to internet outage. Tried it out successfully.
is to possible to solve multiple equations which are dependent on each
other....

Chris Smith

unread,
Apr 29, 2012, 6:10:34 AM4/29/12
to sy...@googlegroups.com
Yes. That was shown in the docstring of the ssolve function that I
sent in my reply:

>>> ssolve('''
... y=x+3
... x+y=4''')
{x: 1/2, y: 7/2}

If you don't use ssolve then you would have to do something like
`solve([y - (x+3), x + y - 4])`. There is no need to list the
variables if there are as many variables as there are equations (but
you could write `solve([y - (x+3), x + y - 4], x, y)` to make it clear
(or unambiguous) that you want a solution for x and y.

/c

phneoix

unread,
May 8, 2012, 4:42:46 AM5/8/12
to sy...@googlegroups.com
values={T: 300, a: 3, f: 6, W: 200}

print sy.solve([
    sy.Eq(f, m*a).subs(values),
    sy.Eq(T, f*d).subs(values),
    sy.Eq(W, m*g).subs(values)
    ])

>>>    For nonlinear systems of equations, symbols should be
    given as a list so as to avoid ambiguity in the results.
    solve sorted the symbols as [d, g, m]
[(50, 100, 2)]


for ssolve function i am getting...

print ssolve('''
f=a*m
W=g*m
T=d*f
m=?
f=6.0
a=3.0
W=200
g=?
T=300
d=?
''')

raise DomainError("can't compute a Groebner basis over %s" % domain)
DomainError: can't compute a Groebner basis over RR

Chris Smith

unread,
May 8, 2012, 4:56:49 AM5/8/12
to sy...@googlegroups.com
On Tue, May 8, 2012 at 2:27 PM, phneoix <neo.s...@gmail.com> wrote:
> values={T: 300, a: 3, f: 6, W: 200}
>
> print sy.solve([
>     sy.Eq(f, m*a).subs(values),
>     sy.Eq(T, f*d).subs(values),
>     sy.Eq(W, m*g).subs(values)
>     ])
>
>>>>    For nonlinear systems of equations, symbols should be
>     given as a list so as to avoid ambiguity in the results.
>     solve sorted the symbols as [d, g, m]
> [(50, 100, 2)]
>
>
> for ssolve function i am getting...

Make sure you are in the current master and that your ssolve looks like this:


def ssolve(s, *v):
"""
Solve lines of equations as a set of equations:
>>> from sympy.my import ssolve
>>> ssolve('''
... y=x+3
... x+y=4''')
{x: 1/2, y: 7/2}

Any line containing an '?' will be ignored.

>>> ssolve('''
... y=x+3
... y=4
... x=?''')
{x: 1, y: 4}
"""
from sympy import Eq, solve, Tuple
eq=[]
for li in [si for si in s.strip().splitlines() if si]:
li.replace('==','=')
if '?' in li: continue
if '=' in li: eq.append(Eq(*[S(p) for p in li.split('=')]))
else: eq.append(S(li))
syms = (v or list(Tuple(*eq).free_symbols))
soln = solve(eq, *syms)
if type(soln) is dict:
return soln
if len(soln) == 1:
return dict(zip(syms, soln[0]))
else:
return [dict(zip(syms, s)) for s in soln]

ans = ssolve('''
f=a*m
W=g*m
T=d*f
m=?
f=6.0
a=3.0
W=200
g=?
T=300
d=?
''')

>>> print filldedent(ans)

{f: 6.00000000000000, m: 2.00000000000000, W: 200.000000000000, d:
50.0000000000000, a: 3.00000000000000, g: 100.000000000000, T:
300.000000000000}

/c

phneoix

unread,
May 8, 2012, 5:29:26 AM5/8/12
to sy...@googlegroups.com
copied and ran your code as it is...
but still getting...
i am using 0.7.1

Traceback (most recent call last):
  File "C:/Documents and Settings/User/Desktop/hh.py", line 45, in <module>
    ''')
  File "C:/Documents and Settings/User/Desktop/hh.py", line 26, in ssolve
    soln = solve(eq, *syms)
  File "C:\Python26\lib\site-packages\sympy\solvers\solvers.py", line 484, in solve
    solution = _solve(f, *symbols, **flags)
  File "C:\Python26\lib\site-packages\sympy\solvers\solvers.py", line 749, in _solve
    result = solve_poly_system(polys)
  File "C:\Python26\lib\site-packages\sympy\solvers\polysys.py", line 44, in solve_poly_system
    return solve_generic(polys, opt)
  File "C:\Python26\lib\site-packages\sympy\solvers\polysys.py", line 178, in solve_generic
    result = solve_reduced_system(polys, opt.gens, entry=True)
  File "C:\Python26\lib\site-packages\sympy\solvers\polysys.py", line 135, in solve_reduced_system
    basis = groebner(system, gens, polys=True)
  File "C:\Python26\lib\site-packages\sympy\polys\polytools.py", line 5308, in groebner

phneoix

unread,
May 8, 2012, 5:38:49 AM5/8/12
to sy...@googlegroups.com
solved,
downloaded latest source from github....

and thanks a lot for prompt reply... :)

Chris Smith

unread,
May 8, 2012, 5:41:54 AM5/8/12
to sy...@googlegroups.com
The version you have might not be the most up to date version of
0.7.1. Have you looked at
https://github.com/sympy/sympy/wiki/Getting-the-bleeding-edge ?

Chris Smith

unread,
May 8, 2012, 5:42:47 AM5/8/12
to sy...@googlegroups.com
Oops. Forgive the redundant post regarding the need to do what you
have already done.

/c

phneoix

unread,
May 8, 2012, 12:16:30 PM5/8/12
to sy...@googlegroups.com
Thanks Chris,
           i always wanted an open source software for modelling math equations... i have been using TKsolver, spreadsheet for that purpose... sympy is really great software with really great guys supporting it....

Thanks a lot...



Chris Smith

unread,
May 8, 2012, 12:32:43 PM5/8/12
to sy...@googlegroups.com
That's what got me interested, too. And the fact that it's in python.
Glad to be of help.

phneoix

unread,
May 13, 2012, 12:12:27 PM5/13/12
to sy...@googlegroups.com
how do i raise an exception if certain equation is unsolvable (maybe due to lack of sufficient data)....

thanks..

Chris Smith

unread,
May 13, 2012, 9:25:33 PM5/13/12
to sy...@googlegroups.com
On Sun, May 13, 2012 at 9:57 PM, phneoix <neo.s...@gmail.com> wrote:
> how do i raise an exception if certain equation is unsolvable (maybe due to
> lack of sufficient data)....
>

I think it already raises an error in such cases. Can you give a
specific example?

Otherwise, you can raise an error. Something like

raise ValueError('that was a bad value: %s' % the_val)
Reply all
Reply to author
Forward
0 new messages