How much do we support the casual user

479 views
Skip to first unread message

Ralf Stephan

unread,
Mar 27, 2018, 3:07:41 AM3/27/18
to sage-devel
Hello,
I thought I'd try Sage for a casual computation. I was interested in which numbers of the form (2^n - (-1)^n)/3 are prime. I first tried out n=23:

sage: (2^23+1)/3
2796203
sage
: _.is_prime()
False
sage
: factor(2796203)
2796203

It turns out that Rational.is_prime does not exist and the fallback gives false answers.

Then, I tried to print a list of primes of the above form, using the global is_prime:

sage: for n in range(1,100):
....:     if is_prime((2^n - (-1)^n)/3):
....:         print((2^n - (-1)^n)/3)
....:        
sage
:

No output. Turns out `is_prime(ZZ((2^n - (-1)^n)/3))` works. Really? How long does Sage exist without a fix to that? This goes beyond "serious lack of reviewers" and "dev shortage".

There was always the notion that you shouldn't "team up" for ticket review. I'm now breaking it. If YOU are interested in fixing the above or similar problems please mail me. There are also about 25 calculus tickets from me waiting for review. But probably noone is really interested in that either. The algebraists can have their Sage back. Good job.

Simon King

unread,
Mar 27, 2018, 4:08:18 AM3/27/18
to sage-...@googlegroups.com
Hi Ralf,

On 2018-03-27, Ralf Stephan <gtr...@gmail.com> wrote:
> sage: (2^23+1)/3
> 2796203
> sage: _.is_prime()
> False
> sage: factor(2796203)
> 2796203
>
> It turns out that Rational.is_prime does not exist and the fallback gives
> false answers.

My first association: We should change the printed form of a rational
number. The integer 2796203 should print as 2796203, but the
corresponding rational number should be printed as 2796203/1.

In that way, if a user copy-and-pastes printed output back into Sage,
there won't be a confusion between integers and rationals.

I know that it is hardly possible to achieve that pasting of printed
output will ALWAYS create a copy of the printed object. However, in
cases where it is easily possible (the real number 1 should print as
1.0, the rational number 1 should print as 1/1, the complex number 1
should print as 1.0+0.0*I etc), we should do it.

My second association: The fallback of is_prime should print a clear warning
in the case that the input's parent is a field. Such as:
WARNING: The given number is defined as element of <self.parent()>,
which is a field. There are no prime numbers in a field, so, probably
you want to convert the number into <self.parent().ring_of_integers()>.

It might be good to add an optional argument to the method that allows to
switch the warning off.

> Then, I tried to print a list of primes of the above form, using the global
> is_prime:
>
> sage: for n in range(1,100):
> ....: if is_prime((2^n - (-1)^n)/3):
> ....: print((2^n - (-1)^n)/3)
> ....:
> sage:
>
> No output. Turns out `is_prime(ZZ((2^n - (-1)^n)/3))` works. Really? How
> long does Sage exist without a fix to that?

I suppose you are aware that from a maths point of view it isn't a bug,
since your code is (implicitly!) asking for prime numbers in QQ.

However, I agree that it is (for most users) unintended behaviour, and
as a corollary to "explicit is better than implicit", we have "implicit
is not as good as explicit".

I believe, when mathematically sound behaviour of SageMath is very likely
not what a user wants, then printing a fat warning that can optionally
be switched off (as above) is the correct fix. Just don't raise an error,
and please do not change the function to give a mathematically wrong answer
((3/1).is_prime() returning "True" would be wrong).

Best regards,
Simon

Simon King

unread,
Mar 27, 2018, 4:17:54 AM3/27/18
to sage-...@googlegroups.com
On 2018-03-27, Simon King <simon...@uni-jena.de> wrote:
> I know that it is hardly possible to achieve that pasting of printed
> output will ALWAYS create a copy of the printed object. However, in
> cases where it is easily possible (the real number 1 should print as
> 1.0, the rational number 1 should print as 1/1, the complex number 1
> should print as 1.0+0.0*I etc), we should do it.

I just notice that we have the above for real numbers already. However:
sage: (1+0*I).parent()
Symbolic Ring

As a casual user I would expect that the above number is a complex
number, not a symbolic expression.

John Cremona

unread,
Mar 27, 2018, 4:19:07 AM3/27/18
to SAGE devel
Ralf, if you use // instead of / then it will do integer division and return integers.

sage: for n in prime_range(100):
....:     p = (2^n-(-1)^n)//3
....:     if p.is_prime():
....:         print p
....:         
3
11
43
683
2731
43691
174763
2796203
715827883
2932031007403
768614336404564651
201487636602438195784363

This is completely independent of Simon's answer!

Whether a ring element is prime or irreducible depends on its parent.  3 is irreducible in ZZ but not in QQ.  Similarly 3*X+3 is irreducible in QQ[X] but not in ZZ[X]:

sage: x=polygen(QQ)
sage: (3*x+3).is_irreducible()
True
sage: x=polygen(ZZ)
sage: (3*x+3).is_irreducible()
False

This is mathematically correct but also confusing for many people since you cannot tell just by looking at an object what its parent is.  The logical extension from Simon's reply would be to give the parent of every object displayed...

John


--
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 sage-devel+unsubscribe@googlegroups.com.
To post to this group, send email to sage-...@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Vincent Delecroix

unread,
Mar 27, 2018, 4:29:05 AM3/27/18
to sage-...@googlegroups.com


On 27/03/2018 10:05, Simon King wrote:
> Hi Ralf,
>
> On 2018-03-27, Ralf Stephan <gtr...@gmail.com> wrote:
>> sage: (2^23+1)/3
>> 2796203
>> sage: _.is_prime()
>> False
>> sage: factor(2796203)
>> 2796203
>>
>> It turns out that Rational.is_prime does not exist and the fallback gives
>> false answers.
>
> My first association: We should change the printed form of a rational
> number. The integer 2796203 should print as 2796203, but the
> corresponding rational number should be printed as 2796203/1.
>
> In that way, if a user copy-and-pastes printed output back into
> Sage, there won't be a confusion between integers and rationals. >
> I know that it is hardly possible to achieve that pasting of printed
> output will ALWAYS create a copy of the printed object. However, in
> cases where it is easily possible (the real number 1 should print as
> 1.0, the rational number 1 should print as 1/1, the complex number 1
> should print as 1.0+0.0*I etc), we should do it.

In plenty of CAS/python packages the difference is indeed explicit and I
think that it is helpful to understand what is happening. And it would
be helpful that copy/paste is working more consistently for basic Sage
types.

Note that a real number is not a good concept in computer science

sage: CDF(1)
1.0
sage: RealField(5)(1)
1.0
sage: RealField(6)(1)
1.0

and we also have other rings to treat like AA, QQbar, number fields,
polynomials...

sage: QuadraticField(2).gen()
a
sage: QuadraticField(-1).gen()
a

sage: ZZ['x']('x')
x
sage: ZZ['x','y']('x')
x
sage: QQ['x']('x')
x
sage: SR('x')
x

So +1 for this idea but it should be carefully designed.
On the other hand we have some compatibility between ring of integer and
fraction field such as

sage: (3/40).factor()
2^-3 * 3 * 5^-1
sage: (4/3).gcd(2/9)
2/9
sage: (4/3).lcm(2/9)
4/3

Vincent

Ralf Stephan

unread,
Mar 27, 2018, 4:41:28 AM3/27/18
to sage-devel


On Tuesday, March 27, 2018 at 10:08:18 AM UTC+2, Simon King wrote:
...since your code is (implicitly!) asking for prime numbers in QQ.

However, I agree that it is (for most users) unintended behaviour, and
as a corollary to "explicit is better than implicit", we have "implicit
is not as good as explicit".

There are some design decisions affecting functions. The member function is_prime certainly should be specialized. The global function however should be helpful and return useful results. Only if the user states explcitly (either by using the member function, or giving a keyword/argument to global) should there be explicit behaviour. I know this crystallized only recently but there we are.

John Cremona

unread,
Mar 27, 2018, 4:42:13 AM3/27/18
to SAGE devel
Those are good examples.   A purist might object (and I am sure has done so on this mailing list) that factoring a rational such as 3/40 is silly since it is a unit in the field QQ, but we make a very useful (for everyday work by experts and for beginners) special case.  In a sense, QQ knows that it is the field of fractions of a unique factorization domain ZZ so that if you ask for something like a factorization or a gcd *or a primality test* then *of course* you mean that with respect to the parent ZZ not QQ.

Another place where useful "abuse notation" like this is in ideals of number fields, which include all nonzero fractional ideals.

However pedantic you are it is very hard indeed to justify this for a package which is intended for a wide class of users:

sage: a = 300/100
sage: a
3
sage: a in ZZ
True
sage: a.is_prime()
False

!

John

 


Vincent

Marc Mezzarobba

unread,
Mar 27, 2018, 5:21:31 AM3/27/18
to sage-...@googlegroups.com
John Cremona wrote:
> However pedantic you are it is very hard indeed to justify this for a
> package which is intended for a wide class of users:
>
> sage: a = 300/100
> sage: a
> 3
> sage: a in ZZ
> True
> sage: a.is_prime()
> False

Yes, but having a.is_prime() return True may break generic code written
for arbitrary commutative rings that needs to specialize gracefully to
fields. This looks less likely with Vincent's examples, though factor()
may be a borderline case.

--
Marc

Erik Bray

unread,
Mar 27, 2018, 8:20:46 AM3/27/18
to sage-devel
What about adding an optional argument to the is_prime()
method--something like a.is_prime(as_element_of=ZZ). It's kind of a
wordy (though I'm sure there's a more succinct spelling) way to write
ZZ(a).is_prime() but at least it's still precise about what you're
asking.

Michael Orlitzky

unread,
Mar 27, 2018, 11:40:10 AM3/27/18
to sage-...@googlegroups.com
On 03/27/2018 03:07 AM, Ralf Stephan wrote:
> Hello,
> I thought I'd try Sage for a casual computation.

My favorite bug from when I was an undergrad...

sage: B = matrix([[ -3, 2, 1 ],
....: [ 2,-4, 4 ],
....: [ 1, 2,-5 ]])
sage: B.rank()
2
sage: (0.5*B).rank()
3
sage: (2 * 0.5*B).rank()
3
sage: (2 * 0.5*B) == B
True

William Stein

unread,
Mar 27, 2018, 12:18:37 PM3/27/18
to sage-...@googlegroups.com
I don’t consider that a bug. 




--
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 sage-devel+...@googlegroups.com.

To post to this group, send email to sage-...@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.
--
-- William Stein

Michael Orlitzky

unread,
Mar 27, 2018, 12:21:55 PM3/27/18
to sage-...@googlegroups.com
On 03/27/2018 12:18 PM, William Stein wrote:
>
> I don’t consider that a bug. 
>

I know, but ask anyone without a PhD in math.

William Stein

unread,
Mar 27, 2018, 12:23:07 PM3/27/18
to sage-...@googlegroups.com
There are similar examples in MATLAB, involving rational numbers, implicit floating point, etc.

--
-- William Stein

Nils Bruin

unread,
Mar 27, 2018, 12:23:07 PM3/27/18
to sage-devel
On Tuesday, March 27, 2018 at 12:07:41 AM UTC-7, Ralf Stephan wrote:
Hello,
I thought I'd try Sage for a casual computation. I was interested in which numbers of the form (2^n - (-1)^n)/3 are prime. I first tried out n=23:

sage: (2^23+1)/3
2796203
sage
: _.is_prime()
False
sage
: factor(2796203)
2796203

Just as a data point: my magma initialization file contains:

intrinsic Factorisation(n::FldRatElt) -> SeqEnum
  L
,u:=Factorisation(Numerator(n));
  L
:= L cat [ <u[1],-u[2]> : u in Factorisation(Denominator(n))];
 
return L,u;
end intrinsic;

intrinsic
Factorisation(n::FldFunRatMElt) -> SeqEnum
  L
,u:=Factorisation(Numerator(n));
  L
:= L cat [ <u[1],-u[2]> : u in Factorisation(Denominator(n))];
 
return L,u;
end intrinsic;

intrinsic
Factorisation(n::FldFunRatUElt) -> SeqEnum
  L
,u:=Factorisation(Numerator(n));
  L
:= L cat [ <u[1],-u[2]> : u in Factorisation(Denominator(n))];
 
return L,u;
end intrinsic;

intrinsic
Factor(a::.)->SeqEnum
 
return Factorisation(a);
end intrinsic;



just because whenever I want to factor an element from a field of fractions, I am interested in the factorization of the numerator and the denominator.

I'd be in favor of adapting the globals namespace factorization routine to do something similar in sage. I think

sage: is_prime(12/4)
False

is so bad that it forces us to special-case something in the toplevel is_prime as well. I'd hope we can leave the methods as-is. It means that library-code should NOT use the top-level is_prime (but it's unlikely it does, and it's a bad idea anyway--method versions are very likely more efficient and probably more appropriate)

William Stein

unread,
Mar 27, 2018, 12:35:34 PM3/27/18
to sage-devel
On Tue, Mar 27, 2018 at 9:23 AM, Nils Bruin <nbr...@sfu.ca> wrote:
> On Tuesday, March 27, 2018 at 12:07:41 AM UTC-7, Ralf Stephan wrote:
>>
>> Hello,
>> I thought I'd try Sage for a casual computation. I was interested in which
>> numbers of the form (2^n - (-1)^n)/3 are prime. I first tried out n=23:
>>
>> sage: (2^23+1)/3
>> 2796203
>> sage: _.is_prime()
>> False
>> sage: factor(2796203)
>> 2796203
>>
> Just as a data point: my magma initialization file contains:
>
> intrinsic Factorisation(n::FldRatElt) -> SeqEnum
> L,u:=Factorisation(Numerator(n));
> L:= L cat [ <u[1],-u[2]> : u in Factorisation(Denominator(n))];
> return L,u;
> end intrinsic;

Just curious -- does that have the *potential* to break Magma library
code? E.g., maybe deep in some package code I wrote 20 years ago
for Magma, I use Factorization on a reational, and assume that the
output is "trivial". (I'm pretty sure I didn't, but...)



--
William (http://wstein.org)

Nils Bruin

unread,
Mar 27, 2018, 12:43:00 PM3/27/18
to sage-devel
On Tuesday, March 27, 2018 at 9:35:34 AM UTC-7, William wrote:
Just curious -- does that have the *potential* to break Magma library
code?  E.g., maybe deep in some package code I wrote 20 years ago
for Magma, I use Factorization on a reational, and assume that the
output is "trivial".   (I'm pretty sure I didn't, but...)

Yes, so if I do run into a bug I feel like reporting, I'll run it through "magma -n" if I don't forget, to check that my customizations aren't to blame.

John Cremona

unread,
Mar 27, 2018, 12:59:41 PM3/27/18
to SAGE devel
Surely not, since on a vanilla Magma session an error is raised if the argument is rational:
> Factorization(6/2);

>> Factorization(6/2);
                ^
Runtime error in 'Factorization': Bad argument types
Argument types given: FldRatElt


 

--
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 sage-devel+unsubscribe@googlegroups.com.

William Stein

unread,
Mar 27, 2018, 1:12:33 PM3/27/18
to sage-devel
On Tue, Mar 27, 2018 at 9:59 AM, John Cremona <john.c...@gmail.com> wrote:
>
>
> On 27 March 2018 at 17:43, Nils Bruin <nbr...@sfu.ca> wrote:
>>
>> On Tuesday, March 27, 2018 at 9:35:34 AM UTC-7, William wrote:
>>>
>>> Just curious -- does that have the *potential* to break Magma library
>>> code? E.g., maybe deep in some package code I wrote 20 years ago
>>> for Magma, I use Factorization on a reational, and assume that the
>>> output is "trivial". (I'm pretty sure I didn't, but...)
>>>
>> Yes, so if I do run into a bug I feel like reporting, I'll run it through
>> "magma -n" if I don't forget, to check that my customizations aren't to
>> blame.
>
>
> Surely not, since on a vanilla Magma session an error is raised if the
> argument is rational:
>> Factorization(6/2);
>
>>> Factorization(6/2);
> ^
> Runtime error in 'Factorization': Bad argument types
> Argument types given: FldRatElt

Thanks. By the way, in Magma:

> IsPrime(3/1);
false
> IsPrime(3);
true

so a similar overloading of isPrime by Nils would potentially break things.

--
William (http://wstein.org)

Ralf Stephan

unread,
Mar 27, 2018, 1:48:34 PM3/27/18
to sage-devel
Nils,

See https://trac.sagemath.org/ticket/21067

for a rational factor_list().

Nils Bruin

unread,
Mar 27, 2018, 2:06:43 PM3/27/18
to sage-devel
I don't think that helps casual user's API at all. If I have to write SR(12/4).factor_list(), I'd rather write ZZ(12/4).factor(). In fact, in sage we already have:
sage: factor(12/21)
2^2 * 7^-1
so no complaints there.

I think we can just put some novice-friendly logic in is_prime rather than have the current implementation:
    try:
       
return n.is_prime()
   
except (AttributeError, NotImplementedError):
       
return ZZ(n).is_prime()



William Stein

unread,
Mar 27, 2018, 2:12:59 PM3/27/18
to sage-devel
But if n = 12/4, then n.is_prime() does not raise an error, since
is_prime is defined in element.pyx in a generic way for ring elements.

If we are going to change something in this case, probably Simon's
suggestion to have a warning (that can be turned off) be printed by
the top-level globalsI() is_prime when confronted with a field element
seems best... It definitely won't break anybody's code, and avoids
Ralf's confusion.

William

David Roe

unread,
Mar 27, 2018, 2:23:56 PM3/27/18
to sage-devel

Michael Orlitzky

unread,
Mar 27, 2018, 2:55:02 PM3/27/18
to sage-...@googlegroups.com
On 03/27/2018 12:22 PM, William Stein wrote:
>
> There are similar examples in MATLAB, involving rational numbers,
> implicit floating point, etc.
>

Does multiplication by a positive scalar change the rank of a matrix?
Can two equal matrices have different ranks?

(I'm willing to entertain the idea that we should give the wrong answer
because MATLAB does too.)

Simon King

unread,
Mar 27, 2018, 3:09:08 PM3/27/18
to sage-...@googlegroups.com
Hi Erik,

On 2018-03-27, Erik Bray <erik....@gmail.com> wrote:
> What about adding an optional argument to the is_prime()
> method--something like a.is_prime(as_element_of=ZZ). It's kind of a
> wordy (though I'm sure there's a more succinct spelling) way to write
> ZZ(a).is_prime() but at least it's still precise about what you're
> asking.

I don't think it'd be a good idea. Reason: What should be the default
value of "as_element_of"? Should it be the parent of "a"? But then, you
immediately have the same problem as we have now, which is the
surprising (to some) fact that (3/1).is_prime() returns False. And the
work-around
(3/1).is_prime(as_element_of=ZZ)
would be more verbous than
ZZ(3/1).is_prime()

Best regards,
Simon

William Stein

unread,
Mar 27, 2018, 3:12:37 PM3/27/18
to sage-devel
Sorry -- I'm not trying to flamebait you, but in order to have any
further discussion, what exactly do you think a floating point number
in a computer is?
What is the mathematical meaning of

>>> float(1)

I just want to make sure, e.g., that you're aware that the set of
floating point numbers with a given precision is not associative under
addition (hence not a ring), so the notion of "wrong answer" is only
meaningful with precise definitions.

Also, in Sage, the definition of x and y being "equal" involves
converting a and b under natural maps to a common parent structure,
then comparing there.

Assuming you have precise definitions, it's possible to answer one of
your questions.

> Can two equal matrices have different ranks?

Yes, e.g.,

X = matrix(GF(3),[0])
Y = matrix(ZZ,[3])
[X == Y, X.rank(), Y.rank()]

--> [True, 0, 1]

There are probably similar examples with floats, where you change precision...

-- William

--
William (http://wstein.org)

Eric Gourgoulhon

unread,
Mar 27, 2018, 3:37:53 PM3/27/18
to sage-devel
Hi Simon, hi Erik,


Why not introducing a different function, is_prime_integer() say, keeping is_prime() as it is now?
Of course, x.is_prime_integer(), or is_prime_integer(x), would return ZZ(x).is_prime().
Then, for the casual user, we should advertise (in examples, tutorials, etc.) the use of is_prime_integer() over is_prime().
Note that the casual user may discover is_prime_integer() by the standard TAB mechanism, since its name starts by "is_prime". Facing the choice between the two functions, he would probably (hopefully?)  opt for is_prime_integer(), which is self-explanatory.

Best regards,

Eric.

Michael Orlitzky

unread,
Mar 27, 2018, 3:57:12 PM3/27/18
to sage-...@googlegroups.com
On 03/27/2018 03:11 PM, William Stein wrote:
>
> Sorry -- I'm not trying to flamebait you, but in order to have any
> further discussion, what exactly do you think a floating point number
> in a computer is?
> What is the mathematical meaning of
>
>>>> float(1)
>

The thread was about casual users, who shouldn't have to care about the
implementation details behind what "0.5" means. To a casual user, 0.5 is
one-half. I didn't bring this up to fight about by pet bug again, but
because of the similarity between this and the fact that 12/4 is not
three. Casual users don't want to hear about the coercion framework,
categories, maps and what-not -- they just want to be able to put in
trivial homework problems and get out the right answers.


>> Can two equal matrices have different ranks?
>
> Yes, e.g.,
>
> X = matrix(GF(3),[0])
> Y = matrix(ZZ,[3])
> [X == Y, X.rank(), Y.rank()]
>
> --> [True, 0, 1]
>

But will MATLAB tell you that two equal matrices have different ranks? I
know sage will do it.

saad khalid

unread,
Mar 27, 2018, 8:03:48 PM3/27/18
to sage-devel
On Tuesday, March 27, 2018 at 2:57:12 PM UTC-5, Michael Orlitzky wrote:The thread was about casual users, who shouldn't have to care about the
implementation details behind what "0.5" means. To a casual user, 0.5 is
one-half. I didn't bring this up to fight about by pet bug again, but
because of the similarity between this and the fact that 12/4 is not
three. Casual users don't want to hear about the coercion framework,
categories, maps and what-not -- they just want to be able to put in
trivial homework problems and get out the right answers.

I definitely agree with Michael, and would go further and say that this doesn't just affect students who want to solve their homework problems, but also people who teach physics and even likely many people with an extensive knowledge of mathematics. I have used Mathematica Far more in my physics classes than I have in my mathematics classes, and my physics professors would definitely expect the rank of these two matrices to be the same, if they are indeed equivalent. Actually, so would all of my mathematics professors, I am fairly sure. In my opinion, the purpose of an ideal CAS is to do mathematics/computation, not get bogged down with the technical details. So even if, by the nature of floating point numbers, the ranks should be different, that is absolutely useless to most people. Most people are not interested in the intricacies of floating point numbers, the CAS should understand the users likely intention and leave these special case usages (such as having floating point numbers work non-associatively) as options (not the default). Why not assume by default that when someone enters a floating point number, they intend it as a member of QQ, at least in this case.


Why not introducing a different function, is_prime_integer() say, keeping is_prime() as it is now?
Of course, x.is_prime_integer(), or is_prime_integer(x), would return ZZ(x).is_prime().
Then, for the casual user, we should advertise (in examples, tutorials, etc.) the use of is_prime_integer() over is_prime().
Note that the casual user may discover is_prime_integer() by the standard TAB mechanism, since its name starts by "is_prime". Facing the choice between the two functions, he would probably (hopefully?)  opt for is_prime_integer(), which is self-explanatory.

I am actually not a fan of this solution, though I definitely appreciate the intention. For me, the goal should be that the easiest to use function(in the sense that it is the one the casual user will likely type) is the one that behaves like the average user would want. So, in this case, it Should assume that 3/1 is referring to the integer 3, use is_prime on the integer, and then also give a warning stating that 3/1 was interpreted as the integer 3. Then, we should have a function like is_prime_in_ring, which functions the way is_prime functions right now, ie it takes into account what the parent was instead of making the common simplification. The warning I mentioned earlier could even tell the use that if they want a ring dependent result, then they should use is_prime_in_ring. Again, the vast majority of users are assuming 3/1 = 3, and paying attention to the parent is a case of special usage.

Andrey Novoseltsev

unread,
Mar 28, 2018, 1:04:03 AM3/28/18
to sage-devel
On Tuesday, 27 March 2018 13:57:12 UTC-6, Michael Orlitzky wrote:
But will MATLAB tell you that two equal matrices have different ranks? I
know sage will do it.

A few years back it could give you completely different eigenvalues for a matrix and its transposition. There are presumably many cases which are "easy to fix" one by one, but it is tricky to take care of all of them at once systematically.

Andrey Novoseltsev

unread,
Mar 28, 2018, 1:09:51 AM3/28/18
to sage-devel
On Tuesday, 27 March 2018 18:03:48 UTC-6, saad khalid wrote:
Why not assume by default that when someone enters a floating point number, they intend it as a member of QQ, at least in this case.

It may be an interesting option to have similar to "automatic_names". It may also be nice to be able to do computations over QQ, but display results as floats of some not very high precision. When I was teaching the simplex method, it was a bit tricky to choose between exact computations with scary looking (for students ;-)) denominators where it is hard to compare two numbers in your head, or inexact computations where you have to feel when a non-zero is actually zero. But I definitely would not want to have either conversion a silent default.

Vincent Delecroix

unread,
Mar 28, 2018, 2:31:40 AM3/28/18
to sage-...@googlegroups.com
Anyway the rank of a floating point matrix is a bad notion. See also my
answer here for the computation of the "kernel"

https://ask.sagemath.org/question/41456/cant-find-matrix-kernel

Another example is the recent thread on sage-devel about p-adic matrices.

I don't think that we should have the same base class for matrix over
exact rings and non-exact ones. But this is drifting away from the
initial thread.

Vincent

Simon King

unread,
Mar 28, 2018, 2:38:57 AM3/28/18
to sage-...@googlegroups.com
On 2018-03-28, saad khalid <saad...@gmail.com> wrote:
> So, in this case,
> it Should assume that 3/1 is referring to the integer 3, use is_prime on
> the integer, and then also give a warning stating that 3/1 was interpreted
> as the integer 3. Then, we should have a function like is_prime_in_ring,
> which functions the way is_prime functions right now, ie it takes into
> account what the parent was instead of making the common simplification.
> The warning I mentioned earlier could even tell the use that if they want a
> ring dependent result, then they should use is_prime_in_ring. Again, the
> vast majority of users are assuming 3/1 = 3, and paying attention to the
> parent is a case of special usage.

That makes sense to me.
Thus I now think, z.is_prime() should roughly work like this:
def is_prime(self):
P = self.parent()
if P in Fields():
try:
R = P.ring_of_integers()
except AttributeError:
R = P
if self not in R:
return False
if P is not R:
deprecation(<relevant ticket>, """
You are testing primality of {},
which was constructed as an element of {}.
We assume that you want a primality test in {}. If this
was not your intention, use .is_prime_in_ring(<ring>)""".format(self,P,R))
P = R
return self.is_prime_in_ring(P)

and

def is_prime_in_ring(self,R=None):
if R is None:
R = self.parent()
return <whether self is a prime in R>

Not so sure if "deprecation" is the right thing, as the plan is not to
eventually remove a functionality. But at least in that way the warning
would be printed only once, and after all it *is* deprecated to use
is_prime for primality test in a field (use is_prime_in_ring instead).

Best regards,
Simon

Simon King

unread,
Mar 28, 2018, 2:44:04 AM3/28/18
to sage-...@googlegroups.com
On 2018-03-28, Andrey Novoseltsev <novo...@gmail.com> wrote:
> On Tuesday, 27 March 2018 13:57:12 UTC-6, Michael Orlitzky wrote:
>>
>> But will MATLAB tell you that two equal matrices have different ranks? I
>> know sage will do it.
>>
>
> A few years back it could give you completely different eigenvalues for a
> matrix and its transposition.

Nice! How did that occur?

Simon King

unread,
Mar 28, 2018, 2:47:17 AM3/28/18
to sage-...@googlegroups.com
Hi Vincent,

On 2018-03-28, Vincent Delecroix <20100.d...@gmail.com> wrote:
> Anyway the rank of a floating point matrix is a bad notion. See also my
> answer here for the computation of the "kernel"

It isn't necessarily a bad notion if you define it in terms of singular
value decomposition.

Cheers,
Simon

Simon King

unread,
Mar 28, 2018, 2:52:17 AM3/28/18
to sage-...@googlegroups.com
Hi Andrey and Saad,

On 2018-03-28, Andrey Novoseltsev <novo...@gmail.com> wrote:
> On Tuesday, 27 March 2018 18:03:48 UTC-6, saad khalid wrote:
>>
>> Why not assume by default that when someone enters a floating point
>> number, they intend it as a member of QQ, at least in this case.
>>
>
> It may be an interesting option to have similar to "automatic_names".

+1

I certainly oppose for it being the default, as when I type in a float
I *want* a float (actually an element of RR).

Cheers,
Simon

Ralf Stephan

unread,
Mar 28, 2018, 3:33:51 AM3/28/18
to sage-devel
Ask yourself, are these arguments you give for current is_prime(x) behaviour not just the inertia of your thinking.

Wolfram tells me plainly "1/3 (2^23 + 1) is a prime number"---no ambiguity, no attempt to show a glimpse of algebraic truth.

Pari gives
? isprime((2^23+1)/3)
%1 = 1

Giac:
>> is_prime((2^23+1)/3)
1

SymPy however:
In [7]: isprime((2**23+1)/3)
Out[7]: False

But then it's clear that the value is not integer:
In [8]: (2**23+1)/3
Out[8]: 2796203.0

Why not improve mathematics? Why not define the primality term you apply in the element is_prime() as having a different name than "prime"? Why not introduce 123/1 as notation to avoid ambiguities in mathematics? I'm quite astonished that mathematicians allow these fuzziness in their language, it is unusual. 

Simon King

unread,
Mar 28, 2018, 4:25:07 AM3/28/18
to sage-...@googlegroups.com
Hi Ralf,

On 2018-03-28, Ralf Stephan <gtr...@gmail.com> wrote:
> Ask yourself, are these arguments you give for current is_prime(x)
> behaviour not just the inertia of your thinking.

No. It is a sign of appreciation of mathematical notions. Sorry to start
with politics here, but I am against populism. And dropping mathematical
rigor in order to get more votes (i.e., more users), just because of some
guess that a large proportion of potential users of maths software might
refuse to start learning about mathematical notions, *is* populism, IMHO.

Also, that attitude is a grave indectment against once own educational
capacity.

Instead, I would strive to improve mathematical knowledge of the users.
Not by letting the user fall into the pitfalls of maths, but by pointing
the users to such pitfalls (warning messages etc.).

> Wolfram tells me plainly "1/3 (2^23 + 1) is a prime number"---no ambiguity,
> no attempt to show a glimpse of algebraic truth.

Shame on Wolfram.

It's the same problem that results from using calculators in school:
Many of my students are uncomfortable with fractions, will even not
simplify 5/10 to 1/2, and will convert 1/4 into 0.25. As a consequence,
they fail tests at university, as they are designed to be easily
solvable with exact computations using paper and pen (I am just grading
such exam).

> But then it's clear that the value is not integer:
> In [8]: (2**23+1)/3
> Out[8]: 2796203.0

As I said in an earlier post, I'd be in favour of changing printed
output of basic number types in Sage, so that pasting output will result
in a copy of the object.

> Why not improve mathematics? Why not define the primality term you apply in
> the element is_prime() as having a different name than "prime"? Why not
> introduce 123/1 as notation to avoid ambiguities in mathematics? I'm quite
> astonished that mathematicians allow these fuzziness in their language, it
> is unusual.

It is not mathematicians being fuzzy, but it is the interplay of
mathematical notions and (unintended?) implications of computations.
Namely, when the user writes x=3/1, she implies that x shall be considered
as an element of QQ, and Sage keeps track of that implication. And then,
there is a clear mathematical notion of primality, which means that there
are no primes in QQ.

Best regards,
Simon


Dima Pasechnik

unread,
Mar 28, 2018, 4:26:31 AM3/28/18
to sage-devel


On Tuesday, March 27, 2018 at 8:07:41 AM UTC+1, Ralf Stephan wrote:
Hello,
I thought I'd try Sage for a casual computation. I was interested in which numbers of the form (2^n - (-1)^n)/3 are prime. I first tried out n=23:

sage: (2^23+1)/3
2796203
sage
: _.is_prime()
False
sage
: factor(2796203)
2796203

It turns out that Rational.is_prime does not exist and the fallback gives false answers.

It's a bug, I think - in a field the notion of prime makes little sense, and thus an error should be raised.

 

Then, I tried to print a list of primes of the above form, using the global is_prime:

sage: for n in range(1,100):
....:     if is_prime((2^n - (-1)^n)/3):
....:         print((2^n - (-1)^n)/3)
....:        
sage
:

No output. Turns out `is_prime(ZZ((2^n - (-1)^n)/3))` works. Really? How long does Sage exist without a fix to that? This goes beyond "serious lack of reviewers" and "dev shortage".

There was always the notion that you shouldn't "team up" for ticket review. I'm now breaking it. If YOU are interested in fixing the above or similar problems please mail me. There are also about 25 calculus tickets from me waiting for review. But probably noone is really interested in that either. The algebraists can have their Sage back. Good job.

TB

unread,
Mar 28, 2018, 4:34:35 AM3/28/18
to sage-...@googlegroups.com
The documentation of RingElement.is_prime [1], which most people will
never read, does give the example of fields, where an element is never
prime.

I am not sure what will be the impact of changing the global is_prime
function (I used it for rings other than ZZ), but updating its
documentation [2] not to say "Return True if n is a prime *number*", and
saying something about rings which are not the integers, is surely
better than the current situation.

Regarding SymPy, I think this is something more general to Python. Even
unrelated to mathematics, if one wants for example to iterate over the
first half of some list, they might use range(n/2) where n is an integer
which raises:
TypeError: range() integer end argument expected, got float.

In such scenarios, the programmer will soon learn about floor division.
The difference with is_prime is that a non-integer is expected...

Regards,
TB

[1]
https://doc.sagemath.org/html/en/reference/structure/sage/structure/element.html#sage.structure.element.RingElement.is_prime
[2]
https://doc.sagemath.org/html/en/reference/rings_standard/sage/arith/misc.html#sage.arith.misc.is_prime

TB

unread,
Mar 28, 2018, 4:50:01 AM3/28/18
to sage-...@googlegroups.com
On 28/03/18 11:22, Simon King wrote:
> As I said in an earlier post, I'd be in favour of changing printed
> output of basic number types in Sage, so that pasting output will result
> in a copy of the object.
>
A bit of future bike-shedding: I would not mind if QQ(3) be printed on
the command line as 3/1 or stay 3, but the LaTeX version is probably a
harder decision. For example,

sage: latex([bernoulli(i) for i in range(10)])
\left[1, -\frac{1}{2}, \frac{1}{6}, 0, -\frac{1}{30}, 0, \frac{1}{42},
0, -\frac{1}{30}, 0\right]

seems IMO nicer than having many "0/1"'s.

Regards,
TB

John Cremona

unread,
Mar 28, 2018, 4:51:07 AM3/28/18
to SAGE devel
On 28 March 2018 at 09:34, TB <math...@gmail.com> wrote:
On 28/03/18 10:33, Ralf Stephan wrote:
Ask yourself, are these arguments you give for current is_prime(x) behaviour not just the inertia of your thinking.

Wolfram tells me plainly "1/3 (2^23 + 1) is a prime number"---no ambiguity, no attempt to show a glimpse of algebraic truth.

Pari gives
? isprime((2^23+1)/3)
%1 = 1

Giac:
 >> is_prime((2^23+1)/3)
1

SymPy however:
In [7]: isprime((2**23+1)/3)
Out[7]: False

But then it's clear that the value is not integer:
In [8]: (2**23+1)/3
Out[8]: 2796203.0

Why not improve mathematics? Why not define the primality term you apply in the element is_prime() as having a different name than "prime"? Why not introduce 123/1 as notation to avoid ambiguities in mathematics? I'm quite astonished that mathematicians allow these fuzziness in their language, it is unusual.


The documentation of RingElement.is_prime [1], which most people will never read, does give the example of fields, where an element is never prime.

I am not sure what will be the impact of changing the global is_prime function (I used it for rings other than ZZ), but updating its documentation [2] not to say "Return True if n is a prime *number*", and saying something about rings which are not the integers, is surely better than the current situation.

I think this is the best solution for the problem originally raised.  is_prime(x) will be true if x is *mathematically* an integer -- whatever its type -- and that integer is a positive prime number.  The documentation would make this very clear.  No change to any x.is_prime() methods would be needed.

The actual origin of the original problem is not any argument of what the definition of a prime element of a ring is at all, it is the fact that  the / operator between two integers (parent ZZ) is rational (parent QQ) regardless of the result, as follows from the policy that the type of the result should only depend on the type of the arguments not on their values.  If (and I am not proposing this) the result of x/y for x, y integers or rationals returned an object with type Integer where possible and only Rational where not, then this entire thread would not have started.
 

Regarding SymPy, I think this is something more general to Python. Even unrelated to mathematics, if one wants for example to iterate over the first half of some list, they might use range(n/2) where n is an integer which raises:
TypeError: range() integer end argument expected, got float.

In such scenarios, the programmer will soon learn about floor division. The difference with is_prime is that a non-integer is expected...

Regards,
TB

[1] https://doc.sagemath.org/html/en/reference/structure/sage/structure/element.html#sage.structure.element.RingElement.is_prime
[2] https://doc.sagemath.org/html/en/reference/rings_standard/sage/arith/misc.html#sage.arith.misc.is_prime

Marc Mezzarobba

unread,
Mar 28, 2018, 5:00:46 AM3/28/18
to sage-...@googlegroups.com
William Stein wrote:
> If we are going to change something in this case, probably Simon's
> suggestion to have a warning (that can be turned off) be printed by
> the top-level globalsI() is_prime when confronted with a field element
> seems best... It definitely won't break anybody's code, and avoids
> Ralf's confusion.

FWIW, Maple has a specific message type ("hint") for things that aren't
really warnings but may help the interactive user do what they want.
These messages are on by default but can be disabled globally.
There may be a use for something similar in Sage (based on the standard
python logging module, for instance).

--
Marc

Marc Mezzarobba

unread,
Mar 28, 2018, 5:07:17 AM3/28/18
to sage-...@googlegroups.com
Simon King wrote:
> That makes sense to me.
> Thus I now think, z.is_prime() should roughly work like this:
> def is_prime(self):
> ...

What about keeping the is_prime() *method* unchanged (except perhaps for
adding an optional warning in the default implementation for field
elements), and restricting the is_prime() *function* to integers--
perhaps allowing it to automatically convert its argument, after a
deprecation period at least?

--
Marc

Simon King

unread,
Mar 28, 2018, 5:28:13 AM3/28/18
to sage-...@googlegroups.com
Hi TB,

On 2018-03-28, TB <math...@gmail.com> wrote:
> A bit of future bike-shedding: I would not mind if QQ(3) be printed on
> the command line as 3/1 or stay 3, but the LaTeX version is probably a
> harder decision. For example,
>
> sage: latex([bernoulli(i) for i in range(10)])
> \left[1, -\frac{1}{2}, \frac{1}{6}, 0, -\frac{1}{30}, 0, \frac{1}{42},
> 0, -\frac{1}{30}, 0\right]
>
> seems IMO nicer than having many "0/1"'s.

That's a different story. latex(...) is (as far as I know) used to
copy-and-past stuff into manuscripts, and to nicely display stuff in the
notebooks. Hence, the problem that pasting back printed output of basic
types may create something that isn't a copy will not occur with latex.

Cheers,
Simon

Erik Bray

unread,
Mar 28, 2018, 6:48:52 AM3/28/18
to sage-devel
+1 to Eric's idea. I think that should resolve the issue reasonably
well, since for the "casual" user we're talking about it's integers
they're probably concerned with--it doesn't need to become a slipper
slope or anything.

As a bonus, the curious undergrad will be surprised that there are
separate is_prime and is_prime_integer and maybe learn something new.

Erik Bray

unread,
Mar 28, 2018, 6:50:00 AM3/28/18
to sage-devel
I think what we really need is more diversity of equivalence
operators, e.g. "~=" ;)

Dima Pasechnik

unread,
Mar 28, 2018, 6:55:07 AM3/28/18
to sage-devel


On Wednesday, March 28, 2018 at 9:25:07 AM UTC+1, Simon King wrote:
Hi Ralf,

On 2018-03-28, Ralf Stephan <gtr...@gmail.com> wrote:
> Ask yourself, are these arguments you give for current is_prime(x)
> behaviour not just the inertia of your thinking.

No. It is a sign of appreciation of mathematical notions. Sorry to start
with politics here, but I am against populism. And dropping mathematical
rigor in order to get more votes (i.e., more users), just because of some
guess that a large proportion of potential users of maths software might
refuse to start learning about mathematical notions, *is* populism, IMHO.

Also, that attitude is a grave indectment against once own educational
capacity.

Instead, I would strive to improve mathematical knowledge of the users.
Not by letting the user fall into the pitfalls of maths, but by pointing
the users to such pitfalls (warning messages etc.).

> Wolfram tells me plainly "1/3 (2^23 + 1) is a prime number"---no ambiguity,
> no attempt to show a glimpse of algebraic truth.

this has nothing to do with algebra; this is a purely (programming, or mathematical) language
issue, laziness vs eagerness. (As well, it's the stuff studied by a fuzzy field called human-computer
interaction). Very often, for interactive computations in particular,
I much prefer the eager way, i.e. the function (is_prime()) to be applied to data would try to coerce the input into
the meaningful domain - in this case ZZ, more generally, say, for algebraic numbers this would be its
ring of integers, etc. 
For non-interactive uses the eagerness might be deadly for performance (although often it is not).

Dima Pasechnik

unread,
Mar 28, 2018, 7:06:29 AM3/28/18
to sage-devel
is_prime() should be restricted to rings in which one can have non-trivial prime elements, e.g.
it has perfect (and different!!!) meaning in ZZ[i], where 2 is not prime, as 2=(1+i)(1-i) or even:

sage: ZZ[I](2).factor()
(-I) * (I + 1)^2

 
--
Marc

Marc Mezzarobba

unread,
Mar 28, 2018, 7:19:59 AM3/28/18
to sage-...@googlegroups.com
Dima Pasechnik wrote:
> is_prime() should be restricted to rings in which one can have
> non-trivial prime elements

Well, that's what I'm doubting. If the goal is that the global
is_prime() function doesn't do anything surprising for people who would
have integers in mind, then it may be better to restrict it to plain
integers.

--
Marc

John Cremona

unread,
Mar 28, 2018, 8:02:41 AM3/28/18
to SAGE devel
I agree with both Marc's last 2 suggestions.   If the global function is_prime() is called on an integer (even of type Rational) it should do the natural thing.  Anything else raises an error with a helpful message that x.is_prime() might be what is wanted.

--
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 sage-devel+...@googlegroups.com.

mforets

unread,
Mar 28, 2018, 8:15:02 AM3/28/18
to sage-devel
One question: if 3/1 is not prime but ZZ(3/1) is, shouldn't 3/1 == ZZ(3/1) return False? (I don't know how does sage evaluate == , is it documented? I searched for "==" in the docs and got nothing, and "equivalence" gives a super long list.)

Martin R

unread,
Mar 28, 2018, 8:22:13 AM3/28/18
to sage-devel
I also think that this (restricting the global function is_prime to input that look like integers) is a very elegant solution.  I would actually guess that novice users tend to try global functions first, and I am often surprised how long it takes some people to discover tab-completion.

Martin

Dima Pasechnik

unread,
Mar 28, 2018, 12:14:00 PM3/28/18
to sage-devel
I think that we just need a beginner mode,
with all such restricted defauls...

kcrisman

unread,
Mar 28, 2018, 1:07:04 PM3/28/18
to sage-devel

I thought I'd try Sage for a casual computation. I was interested in which numbers of the form (2^n - (-1)^n)/3 are prime. I first tried out n=23:

sage: (2^23+1)/3
2796203
sage
: _.is_prime()
False
sage
: factor(2796203)
2796203

It turns out that Rational.is_prime does not exist and the fallback gives false answers.


As a side note, I agree that is_prime and not .is_prime() is much, much more likely for a casual user to do.
 

 
There was always the notion that you shouldn't "team up" for ticket review. I'm now breaking it.

Not at all; there are many fruitful tickets that have had two authors/two reviewers that reviewed each others' changes.  It is hard to get some stuff done otherwise.  Hopefully other developers and the release manager can make sure nothing really egregious like pi == 3 returning True happens, and in practice it has worked well for getting things in that has fewer developers able to review.

 
If YOU are interested in fixing the above or similar problems please mail me. There are also about 25 calculus tickets from me waiting for review. But probably noone is really interested in that either. The algebraists can have their Sage back. Good job.

Yes, that is a real shame.  I will apologize again for simply not being able to do Sage review or development beyond a minimum for several years now.  Certainly people are interested in it working, and you have put in huge amounts of work in making Pynac continue to be viable, for which our thanks are due.  But those who feel competent to review such tickets are probably less thick on the ground than a little while ago.  

That has always been an issue for our development model - reviewing code is one thing, reviewing *math* seems to get people to actively self-deselect from reviewing if it's not their specialty.  I've seen this happen many, many times, though of course not as much among the most-often posting members of this list.  My answer is to get your undergrad/grad students to get things wet by trying those!

Vincent Delecroix

unread,
Mar 28, 2018, 5:39:27 PM3/28/18
to sage-...@googlegroups.com
Have you read my answer on ask!?... You still need an epsilon there.

rjf

unread,
Mar 28, 2018, 11:57:00 PM3/28/18
to sage-devel
There is a history of CAS providing strong mathematical typing as part of
the user interface, as in Sage.  Those systems have been unpopular.
Axiom, FriCAS. Users tend to be mathematicians.

There is a history of pasting on formal mathematical typing on
other systems. Maple, and (I think) ModeReduce.  Unpopular.

There are the rest of the systems that are essentially typeless.
Macsyma/Maxima;  Mathematica, Maple, Reduce,  (almost
every other CAS intended for a general audience).
Widely used, commercially supported, applications and
texts written by a community.   More popular.

Take your pick.

Simon King

unread,
Mar 29, 2018, 1:30:14 AM3/29/18
to sage-...@googlegroups.com
On 2018-03-28, Vincent Delecroix <20100.d...@gmail.com> wrote:
>
>
> On 28/03/2018 08:44, Simon King wrote:
>> Hi Vincent,
>>
>> On 2018-03-28, Vincent Delecroix <20100.d...@gmail.com> wrote:
>>> Anyway the rank of a floating point matrix is a bad notion. See also my
>>> answer here for the computation of the "kernel"
>>
>> It isn't necessarily a bad notion if you define it in terms of singular
>> value decomposition.
>
> Have you read my answer on ask!?... You still need an epsilon there.

No, I didn't, and yes one needs an epsilon, which could be provided to
the rank() method with a reasonable default.

saad khalid

unread,
Mar 29, 2018, 2:01:04 AM3/29/18
to sage-devel

Yes, I definitely agree with that. Do others also feel this would be apropriate? How could we go about implementing this?

William Stein

unread,
Mar 29, 2018, 1:37:03 PM3/29/18
to sage-devel
It's surprisingly easy to implement this, due to how Robert Bradshaw
rewrote this part of the Sage preparser. If you define this
function in a notebook or command line sage session:

def RealNumber(s):
if '.' not in s:
return QQ(s)
a = s.split('.')
return ZZ(a[0]) + ZZ(a[1])/10^len(a[1])

then all real number literals will be interpreted as exact rationals!

sage: 3.45
69/20

sage: matrix(2, [1.5,2.5, 7, 8.333])
[ 3/2 5/2]
[ 7 8333/1000]

sage: 3.5*x^2 - x*1.23445 + 2/3
7/2*x^2 - 24689/20000*x + 2/3

You can similarly change the interpretation of integer literals by
defining "Integer".

https://cocalc.com/share/4a5f0542-5873-4eed-a85c-a18c706e8bcd/support/2018-03-29-103001-RealNumber.ipynb?viewer=share


>
> --
> 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 sage-devel+...@googlegroups.com.
> To post to this group, send email to sage-...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-devel.
> For more options, visit https://groups.google.com/d/optout.



--
William (http://wstein.org)

Nils Bruin

unread,
Mar 29, 2018, 2:56:05 PM3/29/18
to sage-devel
On Thursday, March 29, 2018 at 10:37:03 AM UTC-7, William wrote:

It's surprisingly easy to implement this, due to how Robert Bradshaw
rewrote this part of the Sage preparser.    If you define this
function in a notebook or command line sage session:

def RealNumber(s):
    if '.' not in s:
        return QQ(s)
    a = s.split('.')
    return ZZ(a[0]) + ZZ(a[1])/10^len(a[1])

then all real number literals will be interpreted as exact rationals!

Cool! it does require slightly more complicated string mangling to work in general, though:

sage: 1.3e5
TypeError: unable to convert '3e5' to a rational

William Stein

unread,
Mar 29, 2018, 2:57:32 PM3/29/18
to sage-devel
Thanks -- I should have added that the above was a quick "proof of concept".

William

--
William (http://wstein.org)

Nils Bruin

unread,
Mar 29, 2018, 3:01:03 PM3/29/18
to sage-devel
On Thursday, March 29, 2018 at 11:57:32 AM UTC-7, William wrote:

Thanks -- I should have added that the above was a quick "proof of concept".

In fact, letting 1.3e5 still be parsed as a float literal would make this modified behaviour just extremely annoying rather than completely unworkable :-).

Volker Braun

unread,
Mar 29, 2018, 8:33:07 PM3/29/18
to sage-devel
The obvious answer: Show a warning if you test field elements for primality
* easy to implement using standard Python machinery
* does not introduce backward-incompatibile changes
* is mathematically correct
* informative to casual users
* unlikely to give spurious warnings in existing code

saad khalid

unread,
Mar 29, 2018, 9:17:27 PM3/29/18
to sage-devel
I'm not entirely sure how to implement this though, if we don't want it to be the global behavior. I was considering just implementing it for the rank() function, but I'm assuming it processes the input into the function before it starts running the actual function, right? So it isn't just behavior I could set within the rank function. Would it be possible or desirable to make it so that matrix by scalar multiplication converts the scalar to an element of QQ? Or perhaps rank treats the entries of the matrix as members of QQ? The latter sounds best to me.

Also, with regard to is_prime, would it be possible/easy change the default behavior of is_prime to try to convert the input to an integer if it is a member of QQ and raising an error if it is unable to convert the input to an integer, and give an option/keyword to not do this conversion? Perhaps if the conversion is succesful, a warning could be raised that the conversion was made, in case the user actually did want to check for primality over QQ. Though, Volker Braun's suggestion also sounds good, but I'm not sure how helpful it would be to a beginner if they don't know what a field is. I might suggest a warning which comes up if the user enters an element of QQ that is equivalent to an integer that tells them  to run ZZ(x).is_prime() instead of (x).is_prime, if they to check primality over the integers. However, I'm not sure how elegant this solution is.

On Tuesday, March 27, 2018 at 2:07:41 AM UTC-5, Ralf Stephan wrote:
Hello,
I thought I'd try Sage for a casual computation. I was interested in which numbers of the form (2^n - (-1)^n)/3 are prime. I first tried out n=23:

sage: (2^23+1)/3
2796203
sage
: _.is_prime()
False
sage
: factor(2796203)
2796203

It turns out that Rational.is_prime does not exist and the fallback gives false answers.

Then, I tried to print a list of primes of the above form, using the global is_prime:

sage: for n in range(1,100):
....:     if is_prime((2^n - (-1)^n)/3):
....:         print((2^n - (-1)^n)/3)
....:        
sage
:

No output. Turns out `is_prime(ZZ((2^n - (-1)^n)/3))` works. Really? How long does Sage exist without a fix to that? This goes beyond "serious lack of reviewers" and "dev shortage".

There was always the notion that you shouldn't "team up" for ticket review. I'm now breaking it. If YOU are interested in fixing the above or similar problems please mail me. There are also about 25 calculus tickets from me waiting for review. But probably noone is really interested in that either. The algebraists can have their Sage back. Good job.

Simon King

unread,
Mar 30, 2018, 6:20:39 AM3/30/18
to sage-...@googlegroups.com
+1

mmarco

unread,
Mar 30, 2018, 11:51:49 AM3/30/18
to sage-devel
What about creating a `is_prime_integer` function? Explicit is better than implicit, and in that case we leave no ambiguity in the mathematical sense, but also cover the use case of the casual user.

What i definitely don't want is `.is_prime()` return  `True` when it is applied to an element that is not a prime in its parent, even if it can be naturally mapped to a prime integer (that includes the case of rationals, but also more cases: polynomials, number fields, p-adics...)

John Cremona

unread,
Mar 30, 2018, 12:35:12 PM3/30/18
to SAGE devel
I don't think this will satisfy Ralf's casual user who will see 100 warnings output from their loop and not find any of the primes they were hoping for.

I don't think anyone here would argue with the statement "3 is a prime number" being a correct mathematical statement.

This might confuse the issue even more:

sage: is_even(4/2)
True
sage: is_even(6/2)
False

while 

sage: is_even(5/2)
 
raises a zero-division error!
 

+1

--
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 sage-devel+unsubscribe@googlegroups.com.

Volker Braun

unread,
Mar 30, 2018, 1:22:58 PM3/30/18
to sage-devel
On Friday, March 30, 2018 at 6:35:12 PM UTC+2, John Cremona wrote:
I don't think this will satisfy Ralf's casual user who will see 100 warnings output from their loop and not find any of the primes they were hoping for.

By default, the warning is only shown once in said loop. If the warning is suitably worded it can surely be helpful, something like "use is_prime(ZZ(...)) to convert the number to an integer"

Sebastian Oehms

unread,
Apr 2, 2018, 3:58:36 AM4/2/18
to sage-devel
Hello,

This topic is a good example, that wrong names can be worse than wrong code.

Only the user knows what he has in mind using the adjective "prime":

1) prime in a "narrower sense": being a prime number
2) prime in a "broader sense":  being a prime element of a unital commutative ring

Therefore, the user must have the possibility to solve this ambiguity.

If we will do that by an optional argument (as suggested by Erik Bray), then we have to fix a default! Taking the default to be 1) would prefer the casual user and keep track with popular CAS.

WolframAlpha answers the question "is 3/1 prime?" in the sense of 1) with "true". If you have 2) in mind this seems to be a bug. But to be fair: The result "true" matches the explanation WolframAlpha gives for the adjective "prime" (namely according to 1)). If you ask "is 3/1 a prime element?" then it shows you the definition of "prime element" but does not calculate any thing.

Now, Sage can calculate this, and accordingly gives the answer in the sense of 2) like mathematicians would expect. Does it so, always?

sage: is_prime(I)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
............
TypeError: Unable to coerce I to an integer


This looks as if even Sage is trying to give the answer according to 1), as well!

Nevertheless, taking 2) as default would raise less compatibility problems (and seems to be the favorite in most of the contributions of this thread).

But anyway, IMHO the best thing would be to follow the suggestion of Eric Gourgoulhon, solving the ambiguity by separated function names. But if the name "is_prime" should survive, you will have to make a "default"-decision, as well.


As a newcomer to sage-devel I cannot really say, how painful the most transparent solution would be, but I think it should be taken into account, too:

Deprecation of "is_prime" as function (not as method!!! since there is no ambiguity here) and replace it by two new functions "is_prime_number" and "is_prime_element" (according to the corresponding Wikipedia articles). The first function should try to coerce the input into ZZ and raise an error if this it not possible or not positive. The second one should raise an error if the input is not an element of a unital commutative ring and a warning in the case the ring is a field (according to https://trac.sagemath.org/ticket/25046). In cases as for the SymbolicRing above a NotImplementedError should be raised.

If you think deprecation of "is_prime()" would be to painful, then which of both ("is_prime_number" or "is_prime_element") should keep the name "is_prime"? I found contributions for both possibilities!

Best,
Sebastian

saad khalid

unread,
Apr 9, 2018, 11:12:11 PM4/9/18
to sage-devel
Have we come to any conclusions on what steps should be taken after this topic? What seems to be the concensus? Or, at the very least, could someone give a listing of the options we have so that we can give it a poll or something similar?

William Stein

unread,
Apr 10, 2018, 1:02:18 AM4/10/18
to sage-...@googlegroups.com
On Mon, Apr 9, 2018 at 8:12 PM saad khalid <saad...@gmail.com> wrote:
Have we come to any conclusions on what steps should be taken after this topic? What seems to be the concensus? Or, at the very least, could someone give a listing of the options we have so that we can give it a poll or something similar?


My favorite is to add a once per session warning to the the global is_prime function the first time it receives a field element.  Absolutely no other changes at all. 

--
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 sage-devel+...@googlegroups.com.

To post to this group, send email to sage-...@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.
--
-- William Stein

seb....@gmail.com

unread,
Aug 30, 2021, 1:21:10 PM8/30/21
to sage-devel
FYI: Note that there currently is a ticket(#32321) to make changes to the global `is_prime` function treating the subject discussed here.
Reply all
Reply to author
Forward
0 new messages