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
> 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.
>
Either that or always return a tuple as values in the dictionary.
Aaron Meurer
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)}
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.
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.
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.
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}]`.
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.
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
> --
> 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.
> 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.
>
> 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.
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
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
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.
>
>
>
>>> [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.
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:
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
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.
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
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}
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
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}]
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.
> 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.
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
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.
> >
> >> 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.
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?
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...
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
Can you give an example?
/c
A simple example would be x**2+y**2 == 1 , which gives uncountably many
solutions for (x,y).
Frédéric
But solve doesn't handle such cases. Shouldn't this be a different function than solve?
> 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.
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