I remember that there was a long discussion about this issue many years ago 
(Nils may remember).  At that time the current behavious was decided upon.  
One aspect which seemed important at the time is not to confuse 
unsophisticated users, for example students in first linear algebra 
classes, who could be put off my being told that M = Matrix([[0,2],[1,0]]); 
M.eigenvalues() returned an empty list while they were expecting +sqrt(2), 
-sqrt(2).  The compromise was to use QQbar here, so that returned  
[-1.414213562373095?, 1.414213562373095?] looks like what they would expect 
to see (apart from the ? marks perhaps) and can be further worked with, 
while experts can do more, such as coercing them into number field elements 
or RR or CC etc.

So I would hesitate before switching to a position where only eigenvalues 
in the base ring are returned unless a non-default paramater option is 
provided.  On the other hand, I would support having a ring parameter which 
if None (the default) would revert to the current behavious over QQ.  Then 
there would be no change for beginners, while others would be able to say 
M.eigenvalues(ring=RR) or M.eigenvalues(ring=my_favourite_number_field).

For consistency we should probably do the same thing for roots of 
polynomials in QQ[x].  WIth the above M, M.charpoly().roots() returns [],  
not the same as M.eigenvalues()!  If we were to change roots() (for 
univariate polynomials over QQ only) to match the eigenvalues() behaviour 
it could return roots in QQbar unless you specifically set ring=QQ.

John

On Thursday, 4 December 2025 at 17:57:10 UTC Dima Pasechnik wrote:

> I think "extend=" also can take a concrete field as an argument, as there 
> are cases when you know what it can be, and e.g. number fields are faster 
> than QQbar.
> (or, for instance, you know that the eigenvalues are real, and you want to 
> pass this on)
>
>
> On December 4, 2025 11:24:44 AM CST, Nils Bruin <[email protected]> wrote:
>
>> On Thursday, 4 December 2025 at 01:58:41 UTC-8 vdelecroix wrote:
>>
>> My concrete proposal is 
>>
>> def eivenvalues(self, ring=None, extends=False): 
>> if ring is None: 
>> ring = self.base_ring() 
>> if extends: 
>> ring = ring.algebraic_closure() # or possibly something smarter? 
>> return self.charpoly().roots(ring) 
>>
>>
>> I think you'd end up a little more backwards compatible by making the 
>> default for base ring QQ to be "extends=True".  Otherwise that seems like a 
>> flexible solution to me. In fact, there is already an extend option to the 
>> command! Adding the "ring" parameter would be a change. The default is 
>> "extend=True", so Martin's request is really just to return results in 
>> QQbar always when "extend=True". That's OK, I think. We should check that 
>> with "extend=False" we do return the roots just in the base ring. The 
>> keyword argument is already documented ...
>>
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/sage-devel/65547dd0-a032-4499-a2ac-b6762e3a7015n%40googlegroups.com.

Reply via email to