Ticket #4190 (closed defect: fixed)

Opened 5 years ago

Last modified 4 years ago

[with patches, positive review] division of number field order elements doesn't check for membership

Reported by: davidloeffler Owned by: davidloeffler
Priority: major Milestone: sage-3.2
Component: number theory Keywords:
Cc: robertwb Work issues:
Report Upstream: Reviewers: John Cremona, Robert Bradshaw
Authors: David Loeffler Merged in: 3.2.rc1
Dependencies: Stopgaps:

Description

I think this just about says it all:

sage: OK = NumberField(x^2 - x + 2, 'w').ring_of_integers()
sage: w = OK.ring_generators()[0]
sage: 1/w in OK
True

I tested this for cubic fields as well, and the same problem comes up. I can't work out why this happens -- it must be something weird in the coercion framework, as there isn't a specific method for division or inversion of elements of orders: it falls back to NumberFieldElement?.invert and then somehow coerces the result back to an OrderElement? without doing any checks along the way.

I discovered this when trying to find out whether one element of OK was divisible by another -- "x.divides(y)" raises an error, and "y/x in OK" always returns True, which isn't very helpful; the best I could find was "y in x*OK" which seems to give the right results.

Attachments

4190.patch Download (4.2 KB) - added by davidloeffler 5 years ago.
New patch
4190-part2.patch Download (4.1 KB) - added by davidloeffler 5 years ago.
apply after previous patch

Change History

comment:1 Changed 5 years ago by mabshoff

  • Cc robertwb added

Hi David,

I would assume Robert knows what this is all about, so I am adding him to the CC.

In general it would be good to mention the issue on [sage-devel] so that the right people get a change to become aware of the problem since not too many people read [sage-trac].

Cheers,

Michael

comment:2 Changed 5 years ago by robertwb

_div_ on order elements needs to be written so as to return something that is always in the fraction field, not self. This is an oversight, not by design.

comment:3 Changed 5 years ago by davidloeffler

  • Owner changed from was to davidloeffler

I'll have a go at writing that then.

comment:4 Changed 5 years ago by davidloeffler

  • Status changed from new to assigned
  • Summary changed from division of number field order elements doesn't check for membership to [with patch, needs review] division of number field order elements doesn't check for membership

OK, here's a very small patch. Turns out order elements are a cdef class, so I wrote a _div_c_impl.

I wondered whether the return value should be in the order if that makes sense, and in the fraction field otherwise, but this slowed everything down by a factor of 2 according to timeit() so I made it always return fraction field elements.

comment:5 Changed 5 years ago by robertwb

Good work. Note that as of the latest alpha, both cdef and normal classes use _div_. Also, given the way these two are implemented, you could just reset the _parent slot instead of using the __call__ method which is probably eating up a large chunk of the time.

As for your question about whether or not it belongs in the fraction field, the convention is to have division return elements of the fraction field, so go ahead and remove that commented code.

sage: parent(4/2)
Rational Field

comment:6 follow-up: ↓ 7 Changed 5 years ago by davidloeffler

  • Summary changed from [with patch, needs review] division of number field order elements doesn't check for membership to [with patch, needs work] division of number field order elements doesn't check for membership

OK. I'm not keen on downloading and recompiling each new alpha from scratch -- I don't have a fast enough machine for that sort of game -- so perhaps this one will have to wait for 3.1.4; I've changed the status to "needs work" to reflect this.

(PS. If there's something analogous to sage -upgrade or hg_sage.pull() that I can use to upgrade my sage to the latest alpha without having to recompile all the libraries that haven't changed since 3.1.2 anyway, then I'd be very interested to hear about it.)

comment:7 in reply to: ↑ 6 Changed 5 years ago by mabshoff

Replying to davidloeffler:

Hi David,

OK. I'm not keen on downloading and recompiling each new alpha from scratch -- I don't have a fast enough machine for that sort of game -- so perhaps this one will have to wait for 3.1.4; I've changed the status to "needs work" to reflect this.

There are usually development binaries for sage.math which you just need to unpack on that machine and you are ready to go to do development work in an instant. Ironically there is no 3.1.3.alpha1 binary at the moment since I am valgrinding the release for the next day or so and I cannot bdist since that will impact the running jobs. But there will be an alpha2 binary. If you need a sage.math account just ping me by email.

(PS. If there's something analogous to sage -upgrade or hg_sage.pull() that I can use to upgrade my sage to the latest alpha without having to recompile all the libraries that haven't changed since 3.1.2 anyway, then I'd be very interested to hear about it.)

There is no such thing, even as it has been requested a lot. One thing to do is to unpack the new source tarball and to move the new spkgs into $SAGE_ROOT/spkg/standard and then invoke make. That will pretty much do an in place upgrade.

Cheers,

Michael

Changed 5 years ago by davidloeffler

New patch

comment:8 Changed 5 years ago by davidloeffler

  • Summary changed from [with patch, needs work] division of number field order elements doesn't check for membership to [with patch, needs review] division of number field order elements doesn't check for membership

I've uploaded a new patch, taking into account the changes to the coercion model, which works under 3.1.4 and 3.2.alpha1.

comment:9 Changed 5 years ago by cremona

  • Summary changed from [with patch, needs review] division of number field order elements doesn't check for membership to [with patch, with positive review and a question] division of number field order elements doesn't check for membership

Question: is it necessary to have three versions of this? Would it not be enough to have one and the others would work just by inheritance?

Apart from that, I noticed that the doctest has a duplicate line (repeated 3 times!).

I tried to find out what code is run when you say "a in OK" but I have absolutely no idea. I could not find any __contains__ function which seemed to be relevant. Does this work via some coercion magic, or by chance, or what have I missed?

The patch applies fine to 3.2.alpha3. All tests in number_field/ pass. You should add this doctest (from the original post):

sage: OK = NumberField(x^2 - x + 2, 'w').ring_of_integers()
sage: w = OK.ring_generators()[0]
sage: 1/w in OK
False

comment:10 follow-up: ↓ 11 Changed 5 years ago by davidloeffler

As for the inheritance thing: unfortunately, OrderElement?_relative, OrderElement?_absolute and OrderElement?_quadratic all inherit from the corresponding number field classes, which all have different _ div _ implementations, and multiple inheritance is banned. So there is no one place we can put the method where it will be inherited by everything. Personally I'm not sure I agree on that design decision, but I don't have the skills or the time to reimplement it otherwise.

As far as I can tell, the "a in OK" is calling some very generic code (probably in sage.structure.Parent at a guess) which checks whether or not a.parent() is OK, and if it isn't, attempts to coerce a into OK via OK's call method, returning False if this fails.

I am in India at the moment and it is late evening local time; I will get to work on improving the doctests tomorrow.

comment:11 in reply to: ↑ 10 Changed 5 years ago by cremona

Replying to davidloeffler:

As for the inheritance thing: unfortunately, OrderElement?_relative, OrderElement?_absolute and OrderElement?_quadratic all inherit from the corresponding number field classes, which all have different _ div _ implementations, and multiple inheritance is banned. So there is no one place we can put the method where it will be inherited by everything. Personally I'm not sure I agree on that design decision, but I don't have the skills or the time to reimplement it otherwise.

OK, too bad.

As far as I can tell, the "a in OK" is calling some very generic code (probably in sage.structure.Parent at a guess) which checks whether or not a.parent() is OK, and if it isn't, attempts to coerce a into OK via OK's call method, returning False if this fails.

You are right. In fact one way to see where this is happening is to try OK(1/a) (where 1/a is not in OK) and see where the TypeError? comes from, in this case order.py, in OK's __call__ function.

I am in India at the moment and it is late evening local time; I will get to work on improving the doctests tomorrow.

No hurry. If you had time to look at #4392, even better!

Changed 5 years ago by davidloeffler

apply after previous patch

comment:12 Changed 5 years ago by davidloeffler

  • Summary changed from [with patch, with positive review and a question] division of number field order elements doesn't check for membership to [with patches, with partial review] division of number field order elements doesn't check for membership

I could only find the duplicate line in one of the doctests, but I've killed it there. I also realised that while my patch fixed the div methods it didn't fix the separate invert methods, so I've added a similar fix to those.

comment:13 Changed 5 years ago by cremona

  • Summary changed from [with patches, with partial review] division of number field order elements doesn't check for membership to [with patches, with positive review] division of number field order elements doesn't check for membership

OK (!) so there was only one duplicate. Good to have the __invert__ functions too. I successfully applied the second patch on top of the first one, and all tests in number_field pass.

As far as I can see this is ready to go in.

comment:14 Changed 5 years ago by mabshoff

  • Status changed from assigned to closed
  • Resolution set to fixed
  • Milestone changed from sage-3.2.1 to sage-3.2

Megred both patches in Sage 3.2.rc1

comment:15 Changed 4 years ago by was

  • Summary changed from [with patches, with positive review] division of number field order elements doesn't check for membership to [with patches, positive review] division of number field order elements doesn't check for membership

comment:16 Changed 4 years ago by davidloeffler

  • Reviewers set to John Cremona, Robert Bradshaw
  • Merged in set to 3.2.rc1
  • Authors set to David Loeffler
Note: See TracTickets for help on using tickets.