Opened 5 years ago

Last modified 4 years ago

#16753 needs_work defect

solve of equation system misses trivial simplifications

Reported by: rws Owned by:
Priority: critical Milestone: sage-6.4
Component: calculus Keywords:
Cc: Merged in:
Authors: Akshay Ajagekar Reviewers:
Report Upstream: N/A Work issues:
Branch: u/ajagekar.akshay/Trac16753 (Commits) Commit: 88dec5a75c53522f0a24889b4e60efda0964d700
Dependencies: Stopgaps:

Description (last modified by rws)

Some trivial substitutions are not done by solve:

sage: x,y=var('x,y')
sage: solve([y==exp(x),2*y-exp(x)==1],x,y)
[y == e^x, 2*y - e^x == 1]

and, as reported in http://ask.sagemath.org/question/23652/solve-equations-with-sinx/

sage: solve([y==sin(x),y+4*sin(x)==5],x,y)
[y == sin(x), y + 4*sin(x) == 5]

Change History (12)

comment:1 Changed 5 years ago by rws

  • Description modified (diff)
  • Priority changed from major to critical

Set to critical because it makes Sage look really stupid.

comment:2 Changed 5 years ago by vbraun_spam

  • Milestone changed from sage-6.3 to sage-6.4

comment:3 Changed 4 years ago by ajagekar.akshay

I think it is maxima which is unable to solve the equations and returns

%solve([y = sin(x), y + 4*sin(x) = 5],[x,y])

in this case. Sage converts this to list of solutions. Can we condition sage to return "Unable to solve" instead of returning the equations? while reporting this upstream.

comment:4 Changed 4 years ago by rws

You mean a general change for unsolved equations/relations? That would be a different ticket which you would have to open. I'm not against a change but I'd rather have solve return a set, and in case of unsolved an empty set.

comment:5 Changed 4 years ago by ajagekar.akshay

A test which returned initial function instead of solutions was failing

solve([sin(x)==x,y^2==x],x,y)
Expected:
    [sin(x) == x, y^2 == x]
Got:
    []

I have changed that test. Please have a look.

comment:6 Changed 4 years ago by ajagekar.akshay

  • Branch set to u/ajagekar.akshay/Trac16753

comment:7 Changed 4 years ago by rws

  • Commit set to 1961f9430ee403bb5632853af3e18d2d2c858187

Your ticket branch shows MeatAxe? changes. Probably you branched not from develop. Use git trac checkout to have a proper start.

comment:8 Changed 4 years ago by git

  • Commit changed from 1961f9430ee403bb5632853af3e18d2d2c858187 to 88dec5a75c53522f0a24889b4e60efda0964d700

Branch pushed to git repo; I updated commit sha1. New commits:

88dec5aTrac 16753 : solve of equation system misses trivial simplifications

comment:9 Changed 4 years ago by ajagekar.akshay

Sorry for that mistake.

comment:10 Changed 4 years ago by ajagekar.akshay

  • Authors set to Akshay Ajagekar
  • Status changed from new to needs_review

comment:11 Changed 4 years ago by nbruin

  • Status changed from needs_review to needs_work

This solution doesn't fly. Presently:

sage: solve([x==5],[x])
[x == 5]

with this patch, it would return []. That's bad.

In general, I think it's bad to silently returning an empty list in a case where we know we failed to "solve" the system. An empty list can be interpreted as an inconsistent system of equations.

The original behaviour, returning the original system, indicates better a failure to solve than an empty solution list does. Therefore, I think that is preferable.

You could argue that returning the original system would be "invalid" output, because usually it means that the LH sides of the equations aren't the to-be-solved-for variables and/or the RH sides won't be free of them.

In that case, returning an error is a better solution.

I think the parsing that happens for solution_dict=True is definitely broken:

sage: solve([y == sin(x), y + 4*sin(x) == 5],[x,y],solution_dict=True)
[{y: sin(x)}, {y + 4*sin(x): 5}]

Compared with

sage: solve([x^2==5,y==6],[x,y],solution_dict=True)
[{y: 6, x: -sqrt(5)}, {y: 6, x: sqrt(5)}]

it's clearly very misleading output. So for solution_dict=True I think we have a good case for an error. Without it, I think the current output is misleading. But so is:

sage: solve(x-1,x)
[x == 1]
sage: solve([x-1],[x])
[x == 1]
sage: solve([x-1,y-1],[x,y])
[[x == 1, y == 1]]
sage: solve([x-1],[x],solution_dict=True)
TypeError: 'sage.symbolic.expression.Expression' object is not iterable

(we'd probably be better off if also in the single-variable case we'd also return list-of-lists etc.)

Beware of legacy, though. There might be users out there that have grown fond of this bad behaviour and somehow depend on it.

comment:12 Changed 4 years ago by ajagekar.akshay

sage: solve([x==5],[x])

returns [x == 5] as expected, the changed code gets executed only for system of equations. Even for cases like

sage: solve([x==5,y==2],x,y) 

maxima returns list of list as solution [[x == 5, y == 2]], so an empty set is not returned. I also think returning error would be better for unsolved equations. For TypeError?, the parsing for solution_dict = True can be fixed by checking length of variables list and adding appropriate condition.

Note: See TracTickets for help on using tickets.