realonly in algsys.lisp



Am Sonntag, den 26.04.2009, 14:05 +0400 schrieb Alexey Beshenov:
> The option variable realonly is quite confusing since it does not find
> real solutions, but only solutions which are free of %i (purely using
> freeof).
> 
> For example, when realonly is false,
> 
>   algsys ([x^4 + 1], [x]);
> 
> returns
> 
>   [[x = (-1)^(1/4)],  [x = -(-1)^(1/4)*%i],
>    [x = -(-1)^(1/4)], [x = (-1)^(1/4)*%i]]
> 
> But when realonly is true, it returns
> 
>   [[x = (-1)^(1/4)], [x = -(-1)^(1/4)]]
> 
> while it is natural to expect [].
> 
> 
> Maybe it is better to modify the behavior and filter roots by
> checking something like
> 
>   is_real(x) := is(trigsimp(imagpart(x)) = 0);
> 
> and not just
> 
>   freeof(%i, x)
> 
> With the freeof approach we may also omit real roots of irreducible
> polynomials:
> 
>   sol : map ('rhs, solve (3*x^3  - 3*x + 1));
>   [(sqrt(3)*%i/2-1/2)/(3*(3^-(3/2)*%i/2-1/6)^(1/3))
>     +(3^-(3/2)*%i/2-1/6)^(1/3)*(-sqrt(3)*%i/2-1/2),
>    (3^-(3/2)*%i/2-1/6)^(1/3)*(sqrt(3)*%i/2-1/2)
>     +(-sqrt(3)*%i/2-1/2)/(3*(3^-(3/2)*%i/2-1/6)^(1/3)),
>    (3^-(3/2)*%i/2-1/6)^(1/3)+1/(3*(3^-(3/2)*%i/2-1/6)^(1/3))]
> 
>   map (lambda([x], freeof(%i, x)), sol);
>   [false,false,false]
> 
>   map ('is_real, sol);
>   [true,true,true]
> 
> So when realonly and algexact are set to true,
> 
>   algsys ([3*x^3  - 3*x + 1], [x])
> 
> just returns [].
> 
> 
> What do you think?

Hello Alexey,

I think that it is always good to handle complex expressions more
carefully and complete. A test freeof(%i,x) is a very weak test. The
test function $csign can detect complex and imaginary expressions too.
If we use it for your example, we get:

(%i16) sol : map ('rhs, solve (3*x^3  - 3*x + 1))$

(%i17) map(lambda([x],csign(x)),sol);
(%o17) [complex,complex,complex]

csign also give the result complex for the roots of the first example:

(%i19) csign((-1)^(1/4));
(%o19) complex
(%i20) csign(-(-1)^(1/4));
(%o20) complex

Perhaps csign is a bit more efficient in comparison to the calculation
of the Imaginary part, because $csign stops and returns $complex when a
subexpression is complex.

Because $csign also detects pure imaginary expressions, e.g. csign(%i)
--> imaginary, a test function might be (member ($csign x) '($complex
$imaginary)).

Dieter Kaiser