Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

What is best way to return real solutions?

I'm trying to write a function that filters out non-real solutions returned by solve. For now, I'm using

def select_real(xs):
   return map(lambda eq: eq.lhs() == eq.rhs().real(), filter(lambda eq: not bool(eq.rhs().imag()), xs))

and it works for some simple cases like this

sage: select_real(solve(x^3+8==0, x))
[x == -2]

but this assumes multiple things, like fact that the solve retuns list in the form of actual solutions and imaginary part can be calculated. Generally it is only an ugly hack that I don't like.

I looked at assume(x, 'real') but found out that it does not work ( Ticket #11941 ). I also tried to do check using "in RR", but in above case all 3 solutions gave False. Also at first I tried using eq.full_simplify() in map step above, but it turns out that simplifying returns different root than using real/imag:

sage: ((-8)^(1/3)).full_simplify()
-2^(1/3)
sage: ((-8)^(1/3)).real()
1

After all that, I'm out of ideas. What is considered the best way to obtain only real solutions? Thanks in advance.

What is the best way to return only real solutions?

I'm trying to write a function that filters out non-real solutions returned by solve. For now, I'm using

def select_real(xs):
   return map(lambda eq: eq.lhs() == eq.rhs().real(), filter(lambda eq: not bool(eq.rhs().imag()), xs))

and it works for some simple cases like this

sage: select_real(solve(x^3+8==0, x))
[x == -2]

but this assumes multiple things, like fact that the solve retuns list in the form of actual solutions and imaginary part can be calculated. Generally it is only an ugly hack that I don't like.

I looked at assume(x, 'real') but found out that it does not work ( Ticket #11941 ). I also tried to do check using "in RR", but in above case all 3 solutions gave False. Also at first I tried using eq.full_simplify() in map step above, but it turns out that simplifying returns different root than using real/imag:

sage: ((-8)^(1/3)).full_simplify()
-2^(1/3)
sage: ((-8)^(1/3)).real()
1

After all that, I'm out of ideas. What is considered the best way to obtain only real solutions? Thanks in advance.

click to hide/show revision 3
added explanation why I need this

What is the best way to return only real solutions?

I'm trying to write a function that filters out non-real solutions returned by solve. For now, I'm using

def select_real(xs):
   return map(lambda eq: eq.lhs() == eq.rhs().real(), filter(lambda eq: not bool(eq.rhs().imag()), xs))

and it works for some simple cases like this

sage: select_real(solve(x^3+8==0, x))
[x == -2]

but this assumes multiple things, like fact that the solve retuns list in the form of actual solutions and imaginary part can be calculated. Generally it is only an ugly hack that I don't like.

I looked at assume(x, 'real') but found out that it does not work ( Ticket #11941 ). I also tried to do check using "in RR", but in above case all 3 solutions gave False. Also at first I tried using eq.full_simplify() in map step above, but it turns out that simplifying returns different root than using real/imag:

sage: ((-8)^(1/3)).full_simplify()
-2^(1/3)
sage: ((-8)^(1/3)).real()
1

After all that, I'm out of ideas. What is considered the best way to obtain only real solutions? Thanks in advance.


edit:

I need such functionality because actually I'm preparing materials for high-schoolers who yet do not know about complex numbers, and shouldn't be introduced to them at that moment. My current version (above+extra full_simplify and uniq which are not really part of question) allows me to do for example this:

sage: var('x,a,b,c')                        
(x, a, b, c)
sage: assume(b^2-4*a*c>0)
sage: select_real(solve(a*x^2+b*x+c==0, x))
[x == -1/2*(b - sqrt(-4*a*c + b^2))/a, x == -1/2*(b + sqrt(-4*a*c + b^2))/a]
sage: forget(assumptions())
sage: assume(b^2-4*a*c==0)
sage: select_real(solve(a*x^2+b*x+c==0, x))
[x == -1/2*b/a]
sage: forget(assumptions())                
sage: assume(b^2-4*a*c<0)                  
sage: select_real(solve(a*x^2+b*x+c==0, x))
[]