using results from solve

73 views
Skip to first unread message

Mike

unread,
Apr 18, 2011, 2:47:59 AM4/18/11
to sympy
Hi,
I am using solve to solve higher order simultaneous equations in two
variables. solve is able to do that, however I have not been able to
convert the results to int or float. Specifically I did :

>>> from sympy import Symbol
>>> A=solve((x**2 - 1 + y**2 - 2*x*y-6,3*x**2 + 4*y-2),x,y)

What A looks like can be seen at http://pastebin.com/abWtaxWG (didn't
want to paste a large chunk of text that contains the fractions). On
doing the following, I get an error:
>>> A[0] + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "int") to tuple

From what I understand (and i am new to sympy), the results in A are
nicely formatted and are of the type tuple hence this does not work.
But what can I do to convert them to float.

Also, in general can you comment on how good solve is. I am evaluating
whether to use solve against fsolve. Since fsolve solves multinomial
roots by optimization it can get into local minimas IMO. However, will
using solve from sympy result in a smaller set of problems which can
be solved.

Many thanks
M

Chris Smith

unread,
Apr 18, 2011, 3:31:33 AM4/18/11
to sy...@googlegroups.com
Mike wrote:
>> Hi,
>> I am using solve to solve higher order simultaneous equations in two
>> variables. solve is able to do that, however I have not been able to
>> convert the results to int or float. Specifically I did :
>>
>>>>> from sympy import Symbol
>>>>> A=solve((x**2 - 1 + y**2 - 2*x*y-6,3*x**2 + 4*y-2),x,y)
>>
>> What A looks like can be seen at http://pastebin.com/abWtaxWG (didn't
>> want to paste a large chunk of text that contains the fractions). On
>> doing the following, I get an error:
>>>>> A[0] + 1
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> TypeError: can only concatenate tuple (not "int") to tuple
>>
>> From what I understand (and i am new to sympy), the results in A are
>> nicely formatted and are of the type tuple hence this does not work.
>> But what can I do to convert them to float.

When you're stuck with a problem like this it's a good idea to try solve a toy-class set of equations so you can see more clearly what you are dealing with:

>>> solve((x+y-5,x-y-1),x,y) # a system with a single solution
{x: 3, y: 2}
>>> solve((x+y-5,x-y**2+1),x,y) # s system with two solutions
[(3, 2), (8, -3)]

So you are dealing with the second case. When you type A[0] + 1 you are trying to add 1 to the (x, y) tuple...which doesn't make sense. You can extract your values of x and y and then do something with them, though. Continuing from the previous output...

>>> A = _; xi, yi = A[0]
>>> xi+yi
5



>> Also, in general can you comment on how good solve is. I am
>> evaluating whether to use solve against fsolve. Since fsolve solves multinomial
>> roots by optimization it can get into local minimas IMO. However,
>> will using solve from sympy result in a smaller set of problems which can
>> be solved.
>>

Yes, for now you may run into lots of error-raising experiences. I am waiting for polys12 to get in place and for someone to review the changes I've made to the solver for single equations. Once these are in place the solver situation is going to improve significantly.

/c

Aaron S. Meurer

unread,
Apr 18, 2011, 3:43:07 PM4/18/11
to sy...@googlegroups.com

On Apr 18, 2011, at 1:31 AM, Chris Smith wrote:

> Mike wrote:
>>> Hi,
>>> I am using solve to solve higher order simultaneous equations in two
>>> variables. solve is able to do that, however I have not been able to
>>> convert the results to int or float. Specifically I did :
>>>
>>>>>> from sympy import Symbol
>>>>>> A=solve((x**2 - 1 + y**2 - 2*x*y-6,3*x**2 + 4*y-2),x,y)
>>>
>>> What A looks like can be seen at http://pastebin.com/abWtaxWG (didn't
>>> want to paste a large chunk of text that contains the fractions). On
>>> doing the following, I get an error:
>>>>>> A[0] + 1
>>> Traceback (most recent call last):
>>> File "<stdin>", line 1, in <module>
>>> TypeError: can only concatenate tuple (not "int") to tuple
>>>
>>> From what I understand (and i am new to sympy), the results in A are
>>> nicely formatted and are of the type tuple hence this does not work.
>>> But what can I do to convert them to float.
>
> When you're stuck with a problem like this it's a good idea to try solve a toy-class set of equations so you can see more clearly what you are dealing with:
>
>>>> solve((x+y-5,x-y-1),x,y) # a system with a single solution
> {x: 3, y: 2}
>>>> solve((x+y-5,x-y**2+1),x,y) # s system with two solutions
> [(3, 2), (8, -3)]

Wow, do we really do that? That's a horrible convention.

Aaron Meurer

>
> So you are dealing with the second case. When you type A[0] + 1 you are trying to add 1 to the (x, y) tuple...which doesn't make sense. You can extract your values of x and y and then do something with them, though. Continuing from the previous output...
>
>>>> A = _; xi, yi = A[0]
>>>> xi+yi
> 5
>
>>> Also, in general can you comment on how good solve is. I am
>>> evaluating whether to use solve against fsolve. Since fsolve solves multinomial
>>> roots by optimization it can get into local minimas IMO. However,
>>> will using solve from sympy result in a smaller set of problems which can
>>> be solved.
>>>
>
> Yes, for now you may run into lots of error-raising experiences. I am waiting for polys12 to get in place and for someone to review the changes I've made to the solver for single equations. Once these are in place the solver situation is going to improve significantly.
>
> /c
>

> --
> 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.
>

Vinzent Steinberg

unread,
Apr 19, 2011, 11:24:57 AM4/19/11
to sympy
On Apr 18, 9:43 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote:
> >>>> solve((x+y-5,x-y-1),x,y) # a system with a single solution
> >    {x: 3, y: 2}
> >>>> solve((x+y-5,x-y**2+1),x,y) # s system with two solutions
> >    [(3, 2), (8, -3)]
>
> Wow, do we really do that?  That's a horrible convention.

This is indeed inconsistent. Do you think the latter should be
default, even if there is only one solution?

Vinzent

Aaron S. Meurer

unread,
Apr 19, 2011, 12:16:00 PM4/19/11
to sy...@googlegroups.com

Either that or always return a tuple as values in the dictionary.

Aaron Meurer

Chris Smith

unread,
Apr 20, 2011, 1:45:37 AM4/20/11
to sy...@googlegroups.com

So if there are 4 solution (x, y) = (1, 2), (1, 3), (2, 4), (2, 5) you would get the following?

ans = {x:(1, 1, 2, 2), y:(2, 3, 4, 5)}


Alexey U. Gudchenko

unread,
Apr 20, 2011, 2:29:43 AM4/20/11
to sy...@googlegroups.com
20.04.2011 09:45, Chris Smith пишет:

As variant:
One solution:
{x: 3, y: 2}
Many solutions (therefore means a list of solutions):
[{x: 3, y: 2}, {x: 8, y: -3}]

Yes, duplicities "x", "y", but it is normal, if we represent list of
objects as string.

--
Alexey U.

Mateusz Paprocki

unread,
Apr 20, 2011, 2:58:34 AM4/20/11
to sy...@googlegroups.com
Hi,

This is probably the best solution (as long as we stay with built-in data structures), because this gives the most information and we should also take over-determined systems into account. A problem with dicts is that order of elements depends on the printer, not on the solve order (e.g. solve(..., [y, x]) may give {x: ..., y: ...}), so the result may be misleading (ordered dictionary type was added in Python 2.7). Perfect solution would be to have a Solution class which would preserve all information about a solution and it would allow conversion to dict and/or tuple.
 

Yes, duplicities "x", "y", but it is normal, if we represent list of
objects as string.

--
Alexey U.
--
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.


Mateusz

Alexey U. Gudchenko

unread,
Apr 20, 2011, 3:25:13 AM4/20/11
to sy...@googlegroups.com
20.04.2011 10:58, Mateusz Paprocki пишет:

Solution class is needed indeed. Also, to recognize correctly the
number of solutions with the help of `len` procedure. If we return the
dictionary it is not clear:

>>> len({x: 3, y: 2})
2


>>> [{x: 3, y: 2}, {x: 8, y: -3}]

2 (too)

Or as variant (I don't like), if we return the list [{x: 3, y: 2}] of
length 1, even if one solution is? More typified interface of function
definition in this case, but it is not convinient for the user (he ask
for a solution, and rare expect a few ones).

In any case, a Solution class will isolate and resolve any those
problems (present and, possible, in a future).


--
Alexey U.

Chris Smith

unread,
Apr 20, 2011, 3:45:24 AM4/20/11
to sy...@googlegroups.com
> Solution class is needed indeed. Also, to recognize correctly the
> number of solutions with the help of `len` procedure. If we return the
> dictionary it is not clear:
>
>>>> len({x: 3, y: 2})
> 2
>>>> [{x: 3, y: 2}, {x: 8, y: -3}]
> 2 (too)
>

Until a Solution class exists, the multi-solution case should come back like the single solution: as a list.
So solutions will look like `[1]`, ` [1, 2]`, `[{x: 3, y: 2}]` or `[{x: 3, y: 2}, {x: 8, y: -3}]`.

Alexey U. Gudchenko

unread,
Apr 20, 2011, 5:57:24 AM4/20/11
to sy...@googlegroups.com
20.04.2011 11:45, Chris Smith пишет:

May be....
As temporary solution.

But if a Solution class will exists, it is not necessary to result a
list if one solution only. I have pointed out an advantage of this case
(strict typified interface of function definition) and disadvantage (not
convenient for end-user).

But I can't decide it, because I do not know exactly the politic way in
SumPy for this cases (how to manage with variant results).

My opinion that it would be rather suitable:
`1`, ` [1, 2]`, `{x: 3, y: 2}` or `[{x: 3, y: 2}, {x: 8, y: -3}]`

If Solution class exist, then I check type (list of Solutions or
Solution itself) with easy.

Also, taking into account Mateusz's notes (e.g. about sorting of
dictinary) I think that the issue for Solution class should be created
in issue-tracker too.

--
Alexey U.

Mateusz Paprocki

unread,
Apr 20, 2011, 3:04:13 PM4/20/11
to sy...@googlegroups.com
Hi,

On 20 April 2011 11:55, Aaron S. Meurer <asme...@gmail.com> wrote:
The Solution class is indeed a good idea.

I think it would be best to have a unified data structure independent of the number of solutions.  The reason is that it is not clear from the outset how many solutions an equation or system of equations will have.  That is why I think it would be better to have a list always or a dictionary always (or a list of dictionaries always). The list of dictionaries idea is one of the better ones, in my opinion.

This is what Mathematica does (for example) (it gives a list of rules, which is a list of dicts in Python's terminology). There is one more issue that has to be taken into account: currently it's not easy to substitute results from solve() back to the original equation/set of equations (in a systematic way).
 

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.
>

--
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.


Mateusz

Ronan Lamy

unread,
Apr 20, 2011, 3:05:16 PM4/20/11
to sy...@googlegroups.com
Le mercredi 20 avril 2011 à 12:55 -0600, Aaron S. Meurer a écrit :
> The Solution class is indeed a good idea.
>
Why not a Set, instead of an ad-hoc structure with unclear semantics?

> I think it would be best to have a unified data structure independent
> of the number of solutions. The reason is that it is not clear from
> the outset how many solutions an equation or system of equations will
> have. That is why I think it would be better to have a list always or
> a dictionary always (or a list of dictionaries always). The list of
> dictionaries idea is one of the better ones, in my opinion.

The dictionary keys are completely redundant. A list/set of tuples would
be better IMHO.

Ronan Lamy

unread,
Apr 20, 2011, 3:24:31 PM4/20/11
to sy...@googlegroups.com
Le mercredi 20 avril 2011 à 13:16 -0600, Aaron S. Meurer a écrit :

>
> On Apr 20, 2011, at 1:04 PM, Mateusz Paprocki wrote:
>
> > Hi,
> >
> > On 20 April 2011 11:55, Aaron S. Meurer <asme...@gmail.com> wrote:
> > The Solution class is indeed a good idea.
> >
> > I think it would be best to have a unified data structure
> > independent of the number of solutions. The reason is that
> > it is not clear from the outset how many solutions an
> > equation or system of equations will have. That is why I
> > think it would be better to have a list always or a
> > dictionary always (or a list of dictionaries always). The
> > list of dictionaries idea is one of the better ones, in my
> > opinion.
> >
> >
> > This is what Mathematica does (for example) (it gives a list of
> > rules, which is a list of dicts in Python's terminology). There is
> > one more issue that has to be taken into account: currently it's not
> > easy to substitute results from solve() back to the original
> > equation/set of equations (in a systematic way).
>
>
> If you have a list of dictionaries, you can just do
>
>
> sol = solve(expr, vars)
> expr.subs(sol[0])
> expr.subs(sol[1])
> …
>
>
> or just
>
>
> [expr.subs(i) for i in sol]
>
>
> because subs works with a dictionary. Actually, looking at it this
> way, this data structure is far superior to any of the others.
>
That won't work if there's an infinite number of solutions.

>
> And this is another advantage that a Solution class could offer. We
> could just make expr.subs(Solution) work as you would expect it to.
>
Actually, I don't know what expr.subs(Solution) is supposed to do and I
would expect it to raise an exception.

Brian Granger

unread,
Apr 20, 2011, 3:34:25 PM4/20/11
to sy...@googlegroups.com
On Wed, Apr 20, 2011 at 12:16 PM, Aaron S. Meurer <asme...@gmail.com> wrote:
>
> On Apr 20, 2011, at 1:04 PM, Mateusz Paprocki wrote:
>
> Hi,
>
> On 20 April 2011 11:55, Aaron S. Meurer <asme...@gmail.com> wrote:
>>
>> The Solution class is indeed a good idea.
>>
>> I think it would be best to have a unified data structure independent of
>> the number of solutions.  The reason is that it is not clear from the outset
>> how many solutions an equation or system of equations will have.  That is
>> why I think it would be better to have a list always or a dictionary always
>> (or a list of dictionaries always). The list of dictionaries idea is one of
>> the better ones, in my opinion.
>
> This is what Mathematica does (for example) (it gives a list of rules, which
> is a list of dicts in Python's terminology). There is one more issue that
> has to be taken into account: currently it's not easy to substitute results
> from solve() back to the original equation/set of equations (in a systematic
> way).
>
> If you have a list of dictionaries, you can just do
> sol = solve(expr, vars)
> expr.subs(sol[0])
> expr.subs(sol[1])
> …
> or just
> [expr.subs(i) for i in sol]
> because subs works with a dictionary.  Actually, looking at it this way,
> this data structure is far superior to any of the others.

I agree that the list of dicts is a good option for this.

> And this is another advantage that a Solution class could offer.  We could
> just make expr.subs(Solution) work as you would expect it to.

> Aaron Meurer

--
Brian E. Granger
Cal Poly State University, San Luis Obispo
bgra...@calpoly.edu and elli...@gmail.com

Aaron S. Meurer

unread,
Apr 20, 2011, 3:16:30 PM4/20/11
to sy...@googlegroups.com
On Apr 20, 2011, at 1:04 PM, Mateusz Paprocki wrote:

Hi,

On 20 April 2011 11:55, Aaron S. Meurer <asme...@gmail.com> wrote:
The Solution class is indeed a good idea.

I think it would be best to have a unified data structure independent of the number of solutions.  The reason is that it is not clear from the outset how many solutions an equation or system of equations will have.  That is why I think it would be better to have a list always or a dictionary always (or a list of dictionaries always). The list of dictionaries idea is one of the better ones, in my opinion.

This is what Mathematica does (for example) (it gives a list of rules, which is a list of dicts in Python's terminology). There is one more issue that has to be taken into account: currently it's not easy to substitute results from solve() back to the original equation/set of equations (in a systematic way).

If you have a list of dictionaries, you can just do

sol = solve(expr, vars)
expr.subs(sol[0])
expr.subs(sol[1])

or just

[expr.subs(i) for i in sol]

because subs works with a dictionary.  Actually, looking at it this way, this data structure is far superior to any of the others.

And this is another advantage that a Solution class could offer.  We could just make expr.subs(Solution) work as you would expect it to.

Aaron Meurer

 

Aaron Meurer

Aaron S. Meurer

unread,
Apr 20, 2011, 4:35:01 PM4/20/11
to sy...@googlegroups.com

But the only way to represent an infinite number of solutions is to use a parameter, which should cancel if you substitute it into the expression.

Granted, we should also return a list of the parameters somehow, but I think this is something that would be best done with the Solution class.

Aaron Meurer

>
>>
>> And this is another advantage that a Solution class could offer. We
>> could just make expr.subs(Solution) work as you would expect it to.
>>
> Actually, I don't know what expr.subs(Solution) is supposed to do and I
> would expect it to raise an exception.
>
>
>

Alexey U. Gudchenko

unread,
Apr 20, 2011, 5:30:09 PM4/20/11
to sy...@googlegroups.com
21.04.2011 00:35, Aaron S. Meurer пишет:

>>> [expr.subs(i) for i in sol]
>>>
>>>
>>> because subs works with a dictionary. Actually, looking at it this
>>> way, this data structure is far superior to any of the others.
>>>
>> That won't work if there's an infinite number of solutions.
>
> But the only way to represent an infinite number of solutions is to use a parameter, which should cancel if you substitute it into the expression.
>
> Granted, we should also return a list of the parameters somehow, but I think this is something that would be best done with the Solution class.
>
> Aaron Meurer
>


If follow completely, it would be useful to have container "Solutions"
which enclose to itself some tasks (iterible, or generator for infinity
number, or method with parameter to obtain parametrized set or sequences
of solutions).

(the name-tokens and workflow are rough)
# two solutions
>>> sols = solve(expr, vars)
>>> type(sols)
<Solutions class>
>>> len(sols)
>>> 2
>>> sols
[{x:1, y:2}, {x:-1, y:-2}]
>>> for sol in sols:...

>>> sols.variables
[x, y]


Also it resolve representation if there is only one solution:
# one solutions
>>> sols = solve(expr, vars)
>>> len(sols)
>>> 1
>>> solve(expr, vars) # representation without unnecessary `[` `]`
{x:1, y:2}

# infinity many solutions
>>> sols = solve(expr, vars)
>>> len()
Infinity

# if infinity solutions is related with sequences
>>> sols.can_be_parametrized
True
>>> sols.can_be_parametrized_as_sequences ()
True
>>> sols.parameterize(Symbol(n, integer=true))
{x:2*pi*n, y:2*pi*n + pi}


# if a few parameters then multi sequences can be used.
>>> sols.parameterize(n, m)
{x:2*pi*n + m, y:2*pi*n + pi - m}

# if it is not related with Sequences, then generator only
# but this case is complicated, because in general the infinite
# sequences can consist of a finit set part and part with infint
parametrized set.
>>> g = sols.generator()
>>> g.next()
{x:1, y:2}

And so on...


If I prefer the way to use a dictionary or the list of dictionary, it is
possible to hide Solution(s) classes. Nothing prevent to do it.
Doesn't it?

>>> len(sols)
>>> for sol in sols:...
>>> sol
{x:1, y:2}
>>> sol.keys()
[x, y]
>>> sol[x]
>>> 1

And at the same time we do not bound the further development with those
classes.


--
Alexey U.

Aaron S. Meurer

unread,
Apr 20, 2011, 2:55:57 PM4/20/11
to sy...@googlegroups.com
The Solution class is indeed a good idea.

I think it would be best to have a unified data structure independent of the number of solutions. The reason is that it is not clear from the outset how many solutions an equation or system of equations will have. That is why I think it would be better to have a list always or a dictionary always (or a list of dictionaries always). The list of dictionaries idea is one of the better ones, in my opinion.

Aaron Meurer

On Apr 20, 2011, at 3:57 AM, Alexey U. Gudchenko wrote:

Vinzent Steinberg

unread,
Apr 20, 2011, 7:15:58 PM4/20/11
to sympy
On Apr 20, 8:55 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote:
> The Solution class is indeed a good idea.  
>
> I think it would be best to have a unified data structure independent of the number of solutions.  The reason is that it is not clear from the outset how many solutions an equation or system of equations will have.  That is why I think it would be better to have a list always or a dictionary always (or a list of dictionaries always). The list of dictionaries idea is one of the better ones, in my opinion.

Should the Solution() class also represent subspaces which solve e.g.
an undetermined linear equation system?

Vinzent

Aaron S. Meurer

unread,
Apr 20, 2011, 7:38:28 PM4/20/11
to sy...@googlegroups.com

Did you mean "underdetermined"? If so, then I think yes. As I was saying in a previous email, the cleanest way to handle a solution with parameters will be a class like this, I think. For example, the parameters will have to be dummy variables, so they will have to be accessible by themselves, i.e., we would have to return them along with the solution somehow. This can get messy if we return something using just builtin data types. And you should be able to pass a Solution class to solve along with some additional constraints to solve for some of the parameters. That sort of thing should be useful when solving ODEs or PDEs, for example.

Aaron Meurer

Ronan Lamy

unread,
Apr 20, 2011, 8:12:54 PM4/20/11
to sy...@googlegroups.com

I *really* think solve() should return a Set, not an ill-defined ad-hoc
structure. Infinite solution sets don't necessarily have a parameter
(for instance x == tan(x)), or they could be more than one family of
solutions or more than one parameter, or the solution set could contain
families with different dimensionalities. There are a lot of possible
situations but they can all be represented by a set, because that's what
solving an equation means: finding the set of values of the variables
for which the equation holds.


Aaron S. Meurer

unread,
Apr 20, 2011, 8:14:35 PM4/20/11
to sy...@googlegroups.com

I see. You mean a generalized Set class that uses set builder notation.

Yeah, I guess you are right, then. If there are any things we want Solution() to do that Set() wouldn't do, we could just make a Solution class that subclasses from Set.

Aaron Meurer

Vinzent Steinberg

unread,
Apr 21, 2011, 8:38:30 AM4/21/11
to sympy
On 21 Apr., 02:12, Ronan Lamy <ronan.l...@gmail.com> wrote:
> > Did you mean "underdetermined"?

Yes.

> I *really* think solve() should return a Set, not an ill-defined ad-hoc
> structure. Infinite solution sets don't necessarily have a parameter
> (for instance x == tan(x)), or they could be more than one family of
> solutions or more than one parameter, or the solution set could contain
> families with different dimensionalities. There are a lot of possible
> situations but they can all be represented by a set, because that's what
> solving an equation means: finding the set of values of the variables
> for which the equation holds.

+1

Mathematically it is a set, so we should return a set (and not a list
as currently for the onedimensional case). However, we might want to
return additional information like multiplicities, this could be
integrated in a subclass of a set.

Vinzent

Chris Smith

unread,
Apr 22, 2011, 10:53:18 AM4/22/11
to sy...@googlegroups.com
| > I *really* think solve() should return a Set, not an ill-defined ad-hoc
| > structure. Infinite solution sets don't necessarily have a parameter
| > (for instance x == tan(x)), or they could be more than one family of
| > solutions or more than one parameter, or the solution set could contain
| > families with different dimensionalities. There are a lot of possible
| > situations but they can all be represented by a set, because that's what
| > solving an equation means: finding the set of values of the variables
| > for which the equation holds.
|
| +1
|
| Mathematically it is a set, so we should return a set (and not a list
| as currently for the onedimensional case). However, we might want to
| return additional information like multiplicities, this could be
| integrated in a subclass of a set.
|

I don't think we should get hung up on the fact that a set of solutions should be returned as a literal set. How that set gets represented/presented is just an interface issue. I don't see anything wrong with presenting the set as elements in a list. The list representation also allows for unambiguous, non-redundant representation of the symbols and their values. And look at how easy it is to make a replacement dictionary from a list as compared to a dictionary...and I challenge anyone to try do the same with a set in as compact a fashion:

h[4] >>> l=[(x,y),(1,2),(3,4)]
h[4] >>> reps=dict(zip(l[0],l[1])) # first solution is in position 1 of the list
h[4] >>> reps
{x: 1, y: 2}

h[4] >>> d={x:[1,3],y:[2,4]}
h[4] >>> k=d.keys();reps=dict([(k[i],d[k[i]][0]) for i in range(len(d[k[0]]))]) # first soln is element 0
h[4] >>> reps
{x: 1, y: 2}

Vinzent Steinberg

unread,
Apr 23, 2011, 6:20:12 PM4/23/11
to sympy
On 22 Apr., 16:53, "Chris Smith" <smi...@gmail.com> wrote:
> I don't think we should get hung up on the fact that a set of solutions should be returned as a literal set. How that set gets represented/presented is just an interface issue. I don't see anything wrong with presenting the set as elements in a list. The list representation also allows for unambiguous, non-redundant representation of the symbols and their values. And look at how easy it is to make a replacement dictionary from a list as compared to a dictionary...and I challenge anyone to try do the same with a set in as compact a fashion:

>     h[4] >>> l=[(x,y),(1,2),(3,4)]

You could use as well set([...]) here. There is no reason IMHO to use
a list.

>     h[4] >>> reps=dict(zip(l[0],l[1])) # first solution is in position 1 of the list
>     h[4] >>> reps
>     {x: 1, y: 2}
>
>     h[4] >>> d={x:[1,3],y:[2,4]}

I really don't like this representation, I think it just does not work
for multiple solutions. If at all, we should implement it as Alexey
suggested, i.e.:

>>> d = [{x: 1, y: 2}, {x: 3, y: 4}

>     h[4] >>> k=d.keys();reps=dict([(k[i],d[k[i]][0]) for i in range(len(d[k[0]]))]) # first soln is element 0
>     h[4] >>> reps
>     {x: 1, y: 2}

Vinzent

Chris Smith

unread,
Apr 23, 2011, 9:11:04 PM4/23/11
to sy...@googlegroups.com
Vinzent Steinberg wrote:
> On 22 Apr., 16:53, "Chris Smith" <smi...@gmail.com> wrote:
>> I don't think we should get hung up on the fact that a set of
>> solutions should be returned as a literal set. How that set gets
>> represented/presented is just an interface issue. I don't see
>> anything wrong with presenting the set as elements in a list. The
>> list representation also allows for unambiguous, non-redundant
>> representation of the symbols and their values. And look at how easy
>> it is to make a replacement dictionary from a list as compared to a
>> dictionary...and I challenge anyone to try do the same with a set in
>> as compact a fashion:
>
>> h[4] >>> l=[(x,y),(1,2),(3,4)]
>
> You could use as well set([...]) here. There is no reason IMHO to use
> a list.

In the list, that is a literal x and y -- symbols. That's what makes the list less noisy: you get the symbols once, right at the start, and then all the solutions. The dictionary is just too busy with redundant symbols. Easy to use, hard to look at.

/c

Ronan Lamy

unread,
Apr 23, 2011, 9:38:33 PM4/23/11
to sy...@googlegroups.com

But you know the symbols anyway since you just used them to get the list
of solutions. So what's wrong with:

>>> variables = symbols('x y', real=True)
>>> equation = ((x-1)**2 + (y-2)**2)*((x-3)**2 + (y-4)**2)
>>> solutions = solve(equation, variables)
>>> solutions
{(1, 2), (3, 4)}
>>> [dict(zip(variables solution)) for solution in solutions]
[{x: 1, y: 2}, {x: 3, y: 4}]

Chris Smith

unread,
Apr 23, 2011, 9:48:21 PM4/23/11
to sy...@googlegroups.com
Ronan Lamy wrote:
> Le dimanche 24 avril 2011 à 06:56 +0545, Chris Smith a écrit :
>> Vinzent Steinberg wrote:
>>> On 22 Apr., 16:53, "Chris Smith" <smi...@gmail.com> wrote:
>>>> I don't think we should get hung up on the fact that a set of
>>>> solutions should be returned as a literal set. How that set gets
>>>> represented/presented is just an interface issue. I don't see
>>>> anything wrong with presenting the set as elements in a list. The
>>>> list representation also allows for unambiguous, non-redundant
>>>> representation of the symbols and their values. And look at how
>>>> easy it is to make a replacement dictionary from a list as
>>>> compared to a dictionary...and I challenge anyone to try do the
>>>> same with a set in as compact a fashion:
>>>
>>>> h[4] >>> l=[(x,y),(1,2),(3,4)]
>>>
>>> You could use as well set([...]) here. There is no reason IMHO to
>>> use a list.
>>
>> In the list, that is a literal x and y -- symbols. That's what makes
>> the list less noisy: you get the symbols once, right at the start,
>> and then all the solutions. The dictionary is just too busy with
>> redundant symbols. Easy to use, hard to look at.
>
> But you know the symbols anyway since you just used them to get the
> list of solutions. So what's wrong with:
>

You may have not requested an explicit set of symbols and are willing to take whatever you get...in that case you need to know what you got.

h[2] >>> solve([x+y-3,x**2+y-5])
[(-1, 4), (2, 1)]

And if there are many symbols and you just want *some* solution, then it's nice to let solve handle figuring out which set of symbols it can solve for.

Ronan Lamy

unread,
Apr 23, 2011, 10:32:34 PM4/23/11
to sy...@googlegroups.com
But that's just an unsafe convenience that should really only be used in
interactive sessions, in which case you do know what the variables are.

> And if there are many symbols and you just want *some* solution, then
> it's nice to let solve handle figuring out which set of symbols it can
> solve for.
>

I'm not sure what it is you're suggesting, but it sounds like the "do
what I mean" philosophy of coding, which produces "nice" results in
simple cases and debugging nightmares in complex ones.
It should be very easy to figure out what the variables are, basically
just S(equations).free_symbols.

Aaron S. Meurer

unread,
Apr 24, 2011, 12:10:43 AM4/24/11
to sy...@googlegroups.com

I would argue that it's easier to look at, especially if you have a lot of symbols.

Of course, it's more important for the data structure to be useful than for it to be nice to look at (in which case I still would argue for the dictionary, since you can pass it directly to subs).

Aaron Meurer

>
> /c

Chris Smith

unread,
Apr 24, 2011, 6:30:51 AM4/24/11
to sy...@googlegroups.com
>> You may have not requested an explicit set of symbols and are
>> willing to take whatever you get...in that case you need to know
>> what you got.
>>
>> h[2] >>> solve([x+y-3,x**2+y-5])
>> [(-1, 4), (2, 1)]
>>
> But that's just an unsafe convenience that should really only be used
> in interactive sessions, in which case you do know what the variables
> are.

Is it x,y or y,x pairs that you got? Somehow that information needs to be returned.

>
>> And if there are many symbols and you just want *some* solution, then
>> it's nice to let solve handle figuring out which set of symbols it
>> can solve for.
>>
> I'm not sure what it is you're suggesting, but it sounds like the "do
> what I mean" philosophy of coding, which produces "nice" results in
> simple cases and debugging nightmares in complex ones.
> It should be very easy to figure out what the variables are, basically
> just S(equations).free_symbols.

That's not the problem. The problem is knowing which subset lead to an explicit solution. In Chemical Engineering you sometimes solve systems of equations for which there are more parameters than equations. And all you need to characterize the system is some solution to them so you can map out how they behave as the variables change. But you don't care what is treated like a variable and what is a parameter -- you just want something to work with. So this cooked-up example

h[1] >>> solve([x + a**2 + y/b, 1/x - y + a])

indicates you want two of the four variables solved for in terms of the others. So you would be happy to have the solver do the looking for you and get something like:

[(b, (a*y - y**2)/(1 + y*a**2 - a**3)), (x, (-y - b*a**2)/b)]

or, after backsubstitution

{x: (-y - a**2*(a*y - y**2)/(1 + y*a**2 - a**3))*(1 + y*a**2 - a**3)/(a*y - y**2),
b: (a*y - y**2)/(1 + y*a**2 - a**3)}

You're right about the dictionary being easy to use. I would prefer that the format always be the same (as opposed to the current situation: list of expr, dictionary, list of symbols followed by solution tuples.

Ronan Lamy

unread,
Apr 24, 2011, 11:24:06 AM4/24/11
to sy...@googlegroups.com
Le dimanche 24 avril 2011 à 16:15 +0545, Chris Smith a écrit :
> >> You may have not requested an explicit set of symbols and are
> >> willing to take whatever you get...in that case you need to know
> >> what you got.
> >>
> >> h[2] >>> solve([x+y-3,x**2+y-5])
> >> [(-1, 4), (2, 1)]
> >>
> > But that's just an unsafe convenience that should really only be used
> > in interactive sessions, in which case you do know what the variables
> > are.
>
> Is it x,y or y,x pairs that you got? Somehow that information needs to
> be returned.
>
I would say that that information needs to be provided.

> >
> >> And if there are many symbols and you just want *some* solution, then
> >> it's nice to let solve handle figuring out which set of symbols it
> >> can solve for.
> >>
> > I'm not sure what it is you're suggesting, but it sounds like the "do
> > what I mean" philosophy of coding, which produces "nice" results in
> > simple cases and debugging nightmares in complex ones.
> > It should be very easy to figure out what the variables are, basically
> > just S(equations).free_symbols.
>
> That's not the problem. The problem is knowing which subset lead to an
> explicit solution. In Chemical Engineering you sometimes solve systems

No, that's a different problem than what solve() is supposed to do. If
you want that functionality, ask for it explicitly, don't try to graft
it implicitly onto an other function.

> of equations for which there are more parameters than equations. And
> all you need to characterize the system is some solution to them so
> you can map out how they behave as the variables change. But you don't
> care what is treated like a variable and what is a parameter -- you
> just want something to work with. So this cooked-up example
>
> h[1] >>> solve([x + a**2 + y/b, 1/x - y + a])
>
> indicates you want two of the four variables solved for in terms of the
>

How do you know it's two? And how do you know which ones? The only way
to "resist the temptation to guess" is to use all four.

> others. So you would be happy to have the solver do the looking for
> you and get something like:
>
> [(b, (a*y - y**2)/(1 + y*a**2 - a**3)), (x, (-y - b*a**2)/b)]
>
> or, after backsubstitution
>
> {x: (-y - a**2*(a*y - y**2)/(1 + y*a**2 - a**3))*(1 + y*a**2 - a**3)/(a*y - y**2),
> b: (a*y - y**2)/(1 + y*a**2 - a**3)}
>
> You're right about the dictionary being easy to use. I would prefer
> that the format always be the same (as opposed to the current
> situation: list of expr, dictionary, list of symbols followed by
> solution tuples.
>

In any case, the dictionary solution cannot work with infinite solution
sets, so it's not a good choice.

Chris Smith

unread,
Apr 24, 2011, 10:56:50 PM4/24/11
to sy...@googlegroups.com
Ronan Lamy wrote:
>> -- you just want something to work with. So this cooked-up example
>>
>> h[1] >>> solve([x + a**2 + y/b, 1/x - y + a])
>>
>> indicates you want two of the four variables solved for in terms of
>> the
>>
> How do you know it's two? And how do you know which ones? The only way
> to "resist the temptation to guess" is to use all four.

I'm not sure what you mean "use all four". I'm only accustomed to solving for two variables from two equations (except for the case of matching coefficients). But I'm fine with not guessing and having a check that if no variables are given that there are just as many free variables as there are equations. But then we can't expect something like

solve(Eq(a*x**2 + b*x + c, 3*x**2 + 2*x - 4), [a,b,c])

>>
> In any case, the dictionary solution cannot work with infinite
> solution sets, so it's not a good choice.

Can't solve just yield an infinite number of dictionaries, each corresponding to one of the infinite solutions?

Vinzent Steinberg

unread,
Apr 25, 2011, 8:54:28 AM4/25/11
to sympy
On 25 Apr., 04:56, "Chris Smith" <smi...@gmail.com> wrote:
> Can't solve just yield an infinite number of dictionaries, each corresponding to one of the infinite solutions?

No, because infinite could mean uncountable.

Vinzent

Chris Smith

unread,
Apr 25, 2011, 11:58:26 PM4/25/11
to sy...@googlegroups.com

Can you elaborate? By "infinite solutions" I'm thinking things like solutions to sin(x) = 0 being x = 0, pi, -pi, 2*pi, -2*pi, etc...

Haz

unread,
Apr 26, 2011, 12:11:34 AM4/26/11
to sy...@googlegroups.com

That is a countable set -- you can map the integers to those
solutions. Infinite sets can either be countable or uncountable.
Countable essentially means that you can enumerate through them such
that any given element in the set will eventually be reached.

If the solutions to solve are uncountable then you can't "yield an


infinite number of dictionaries, each corresponding to one of the

infinite solutions" since some solutions will never be yielded.

Cheers,
Christian

Chris Smith

unread,
Apr 26, 2011, 1:53:25 AM4/26/11
to sy...@googlegroups.com
Haz wrote:
>> If the solutions to solve are uncountable then you can't "yield an
>> infinite number of dictionaries, each corresponding to one of the
>> infinite solutions" since some solutions will never be yielded.

Can you give an example?

/c

Frédéric Grosshans-André

unread,
Apr 26, 2011, 5:21:37 AM4/26/11
to sy...@googlegroups.com

A simple example would be x**2+y**2 == 1 , which gives uncountably many
solutions for (x,y).

Frédéric

Chris Smith

unread,
Apr 26, 2011, 5:27:36 AM4/26/11
to sy...@googlegroups.com

But solve doesn't handle such cases. Shouldn't this be a different function than solve?

Alexey U. Gudchenko

unread,
Apr 26, 2011, 5:48:02 AM4/26/11
to sy...@googlegroups.com
24.04.2011 08:10, Aaron S. Meurer пишет:

> Of course, it's more important for the data structure to be useful
> than for it to be nice to look at (in which case I still would argue
> for the dictionary, since you can pass it directly to subs).
>
> Aaron Meurer
>

If proper classes will be used to keep the solutions then those problems:
- how to manage with resulted solutions for end user.
- how to manage with constructing of the solutions for developers
- how it will be look in the output (ordinary, pretty late and so on)

will be well separated.

--
Alexey U.

Haz

unread,
Apr 26, 2011, 11:35:01 AM4/26/11
to sy...@googlegroups.com
Ya, I'm not sure the current solve can even handle something that has infinite solutions (countable or otherwise). In which case, debating the returned result is just academic :p.

  Cheers

Vinzent Steinberg

unread,
Apr 26, 2011, 12:07:28 PM4/26/11
to sympy
On Apr 26, 5:35 pm, Haz <christian.mu...@gmail.com> wrote:
> Ya, I'm not sure the current solve can even handle something that has
> infinite solutions (countable or otherwise). In which case, debating the
> returned result is just academic :p.

I think solve() could/should support at least underdetermined linear
systems. Currently we have this behavior for a linear underdetermined
system:

In [6]: A = Matrix([[1,2,3,4],[4,5,6,7]])

In [7]: A.nullspace()
Out[7]:
⎡⎡1 ⎤, ⎡2 ⎤⎤
⎢⎢ ⎥ ⎢ ⎥⎥
⎢⎢-2⎥ ⎢-3⎥⎥
⎢⎢ ⎥ ⎢ ⎥⎥
⎢⎢1 ⎥ ⎢0 ⎥⎥
⎢⎢ ⎥ ⎢ ⎥⎥
⎣⎣0 ⎦ ⎣1 ⎦⎦

In [8]: var('a b c d')
Out[8]: (a, b, c, d)

In [9]: solve([a+2*b+3*c+4*d, 4*a+5*b+6*c+7*d], [a,b,c,d])
Out[9]: {a: c + 2⋅d, b: -3⋅d - 2⋅c}

This is an example for an uncountable amount of solutions (at least
over the real field), because for each real pair you get another
solution. Both express the same solutions, the first one gives a base
of all vectors satisfying the system (aka solution subspace), the
second one returns a parametrized solution depending on other
variables.

Vinzent

Ondrej Certik

unread,
Apr 27, 2011, 8:31:19 PM4/27/11
to sy...@googlegroups.com

I think even Wolfram Alpha doesn't seem to handle such case:

http://www.wolframalpha.com/input/?i=Solve[x**2+%2B+y**2+%3D%3D+1%2C+{x%2C+y}]


Ondrej

Christophe BAL

unread,
Apr 28, 2011, 6:17:31 AM4/28/11
to sy...@googlegroups.com
Hello.

I do not think that is impossible to treat all the equations even the ones having countable sets of solution.

A more realistic feature would be to treat cases of periodic functions like the trigonometric ones using the following tactic.
  1. The equations must be of the kind f(g(x)) = a where f is T-periodic, and g(x) is a function.
  2. Find one possible special solution b : f(b) = a.
  3. Then, we would have to solve the equation g(x) = b + kT where k is an integer and T is the period of the function f.
For example, the preceding method with cos(sqrt(x))=1/sqrt(2), we would have :
  1. b = pi / 4.
  2. We solve the equation sqrt(x) = pi/4 + k*2pi assuming that k is in Z.
  3. Finally, we have : x = (pi/4 + k*2pi)**2 with k in Z.
Simlarly, cos(x**2)=1/sqrt(2) would give x = sqrt(pi/4 + k*2pi) with k in Z where we cannot more precise because this would mean that we would have to sove pi/4 + k*2pi > 0, a problem not easy to solve in general (maybe Semi-algebric Set Theory could manage cases of most usual polynomial inequations).

One last example : cos(sin(x)) = 1.
  1. b = 0.
  2. We solve the equation sin(x) = 0 + k*2pi assuming that k is in Z.
  3. Finally, ... Can sympy knows that abs(k*2pi) > 1 if k in Z \ {0} ?

Best regards.
Christophe.
Reply all
Reply to author
Forward
0 new messages