+1 for separating out undetermined coefficients. I am sure this will break somebody's code. However, I agree that the behavior of solve is so inconsistent that I do not think there is a reasonable way of deprecating this. I generally only use solve in an interactive environment and as little as possible because of how mysterious it is about what choices it is making. I advise my students to avoid using it.
Jonathan On Friday, July 1, 2022 at 6:38:08 AM UTC-5 Oscar wrote: > On Thu, 30 Jun 2022 at 23:27, Chris Smith <[email protected]> wrote: > > > > Nearly from the beginning, `solve` has recognized the `undetermined > coefficients` case wherein a single equation is solved for a set of symbols > which will simultaneously set it equal to zero. This is different than the > normal use of `solve`, however, and might be considered a bug or feature. > As an example, consider: > > > > [in1] solve(a*x + b - (2*x + 4), (a, b)) # solve for a and b > > {a: 2, b: 4} > > [in2] solve(a*x + b - (2*x + 4), exclude=[x]) # solve for as many as > possible, but not x > > {a: 2, b: 4} > > [in3] solve(a*x + b - (2*x + 4), a) # solve for a > > [(-b + 2*x + 4)/x] > > [in4] solve(a*x + b - (2*x + 4)) # solve for anything and tell me what > you did > > [{a: (-b + 2*x + 4)/x}] > > > > The "undetermined coefficients" case is returned from inputs 1 and 2 > while the more usual "solution" is returned from 3 and 4. > > > > The request for comment is whether this feature should be removed from > `solve` so a better defined equation set is provided rather than building > that equation set automatically when this case is detected as > one-equation-many-symbols. > > > > To me it feels natural to get the undetermined coefficients solution > when I ask for many symbols from one equation. If I want sympy to pick any > variable other than some I would use `exclude=some` (where `some` is a list > or set of things to ignore). But not everyone feels this way and refusing > the temptation to guess is important, too. > > It does not feel natural to me at all that solve should arbitrarily > decide to get an undetermined coefficients solution. Also solve is > just flat out inconsistent: > > In [7]: a, b, x = symbols('a, b, x') > > In [8]: eq = a + x*b > > In [9]: solve([eq], [a, b]) > Out[9]: {a: -b⋅x} > > In [10]: nonlinsolve([eq], [a, b]) > Out[10]: {(-b⋅x, b)} > > In [11]: linsolve([eq], [a, b]) > Out[11]: {(-b⋅x, b)} > > Okay so far so good but what happens to solve if I change [eq] to eq: > > In [12]: solve([eq], [a, b]) > Out[12]: {a: -b⋅x} > > In [13]: solve(eq, [a, b]) > Out[13]: {a: 0, b: 0} > > Firstly there should be no distinction between eq and [eq] here. > Secondly in Out[13] solve has arbitrarily decided to completely > reinterpret the problem that was set. The problem is: compute the set > of solutions for a and b to the equation system involving a and b that > is parametrised by a symbol x and give expressions for the solutions > that are valid for almost all possible values of the parameter x. > > That is what {a: -b*x} is. The return value {a:0, b:0} implies that > there is a unique solution for a and b when it is clear that there is > not a unique solution for this underdetermined system. If you > substitute values for x then you get different results: > > In [17]: solve(eq.subs(x, 0), [a, b]) > Out[17]: [(0, b)] > > In [18]: solve(eq, [a, b]) > Out[18]: {a: 0, b: 0} > > Why are these even different types? One is a list of tuples and the > other is a dict... > > The return from solve(eq, [a, b]) should be valid for different values > of the parameter x i.e. ideally these should be equivalent: > > solve(eq.subs(x, value), [a, b]) > solve(eq, [a, b]).subs(x, xvalue) > > (Although it isn't actually possible to use subs directly on the > returned output like that.) > > > Since this behavior is described in the docstring and has been present > for many years it feels like a regression of this feature to me (though to > others it feels like a bug fix). If you use this feature and/or have > comments, please let us know your thoughts on this: > > I don't think this is a feature: > > 1. I doubt that anyone even realises that this is intentional behaviour. > 2. The docstring of solve is impossible to understand. > 3. This feature hardly works because there isn't any way to make solve > consistently behave like this. > > > 1) should it be kept? > > The output should just be changed to be consistent with the > mathematical definition of computing a parametrised solution set. > > > 2) if removed, should there be deprecation? > > It isn't possible to deprecate this. The output just needs to be made > correct. What is possible is adding a separate function that does > undetermined coefficients solving more directly. > > -- > Oscar > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/28bb0400-5835-45c4-8832-ca9a8be79777n%40googlegroups.com.
