-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added new func is_unimodular for square integer matrices #1991
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1991 +/- ##
==========================================
+ Coverage 88.08% 88.14% +0.05%
==========================================
Files 98 98
Lines 36031 36207 +176
==========================================
+ Hits 31737 31913 +176
Misses 4294 4294 ☔ View full report in Codecov by Sentry. |
I am not planning to make further changes to increase test coverage (currently 96%). |
There are some issues, for example, the use of floating point numbers here:
and plenty of unnecessary |
OK, mostly minor syntactic quibbles, right? The code should be mathematically sound. |
The |
What is our stance on supporting platforms which are not 64-bit? I'd guess that 32-bit is probably "impossible" and/or pointless; or do we really support |
On Thu, Jan 16, 2025 at 03:04:39AM -0800, Tommy Hofmann wrote:
There are some issues, for example, the use of floating point numbers here:
```
if det_mod_p > p/2
```
Why is this a problem? This is to get a symmetric lift to char 0...
and plenty of unnecessary `Nemo.` and `;`.
This is in and merged - not because it is perfect, but to get on with
it. It will have to be refactored further as it is part of ongoing
research (e.g. Michael J. recent addition)...
…
--
Reply to this email directly or view it on GitHub:
#1991 (comment)
You are receiving this because you modified the open/close state.
Message ID: ***@***.***>
|
this needs a
I was thinking of things like this
Or I might have mistaken the intended use of floating point stuff here. |
On Thu, Jan 16, 2025 at 04:50:46AM -0800, Tommy Hofmann wrote:
```
for i=1:nrows(A)
A_p = Nemo.mat_entry_ptr(A, i, i)
sub!(A_p, A_p, m)
end
```
this needs a ***@***.***` and similar for the other function.
> Why is this a problem? This is to get a symmetric lift to char 0...
I was thinking of things like this
```
julia> (2^61 + 1) > (2^62 + 2)/2
true
julia> (2^61 + 1) > (2^62 + 2)//2
false
```
Or I might have mistaken the intended use of floating point stuff here.
This is, hopefully, outside the use. The primes should be, depending n
the type, <23 bits or <60 bits, but point taken.
(Also: I have vague feeling it is irrelevant for the correctness - as
we increase our understanding)
…
--
Reply to this email directly or view it on GitHub:
#1991 (comment)
You are receiving this because you modified the open/close state.
Message ID: ***@***.***>
|
On Thu, Jan 16, 2025 at 04:50:46AM -0800, Tommy Hofmann wrote:
```
for i=1:nrows(A)
A_p = Nemo.mat_entry_ptr(A, i, i)
sub!(A_p, A_p, m)
end
```
this needs a ***@***.***` and similar for the other function.
We'll deal with this in the next iteration - there are a bevy of similar
functions still under processing
…
> Why is this a problem? This is to get a symmetric lift to char 0...
I was thinking of things like this
```
julia> (2^61 + 1) > (2^62 + 2)/2
true
julia> (2^61 + 1) > (2^62 + 2)//2
false
```
Or I might have mistaken the intended use of floating point stuff here.
--
Reply to this email directly or view it on GitHub:
#1991 (comment)
You are receiving this because you modified the open/close state.
Message ID: ***@***.***>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't manage to comment on this in time, sorry. It would be good if some of these were still addressed, though
function Nemo.mul!(A::ZZMatrix, m::ZZRingElem) | ||
for i=1:nrows(A) | ||
A_p = Nemo.mat_entry_ptr(A, i, 1) | ||
for j=1:ncols(A) | ||
mul!(A_p, A_p, m) | ||
A_p += sizeof(Int) | ||
end | ||
end | ||
return A | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we already define such a method in src/flint/fmpz_mat.jl
:
function mul!(z::ZZMatrixOrPtr, a::ZZMatrixOrPtr, b::ZZRingElemOrPtr)
@ccall libflint.fmpz_mat_scalar_mul_fmpz(z::Ref{ZZMatrix}, a::Ref{ZZMatrix}, b::Ref{ZZRingElem})::Nothing
return z
end
(and then generic code in AA also makes mul!(::ZZMatrix, ::ZZRingElem)
available.
# add_verbosity_scope(:UnimodVerif) -- see func __init__ in src/Nemo.jl | ||
|
||
####################################################### | ||
# Low-level auxiliary functions -- should be elsewhere? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I would say most of the coded added here should actually be in src/flint/fmpz_mat.jl
return r | ||
end | ||
|
||
function map_entries!(a::fpMatrix, k::Nemo.fpField, A::ZZMatrix) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The argument order clashes with the general map_entries!
signature as defined in AA which is map_entries!(f, dst::MatrixElem{T}, src::MatrixElem{U})
if !is_square(A) | ||
throw(ArgumentError("Matrix must be square")) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is fine, I'd recommend to use the @req
macro liberally for such tests:
if !is_square(A) | |
throw(ArgumentError("Matrix must be square")) | |
end | |
@req is_square(A) "Matrix must be square" |
ZZmodP = Nemo.Native.GF(p; cached = false, check = false) | ||
map_entries!(A_mod_p, ZZmodP, A) | ||
@vtime :UnimodVerif 2 det_mod_p = Int(_det(A_mod_p)) | ||
if det_mod_p > p/2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the cost for converting ints to float etc. here, it could indeed still be avoided here, e.g. via use of >>
if det_mod_p > p/2 | |
if det_mod_p > p>>1 |
return false # obviously not unimodular | ||
end | ||
det_mod_m = det_mod_p | ||
mul!(M, M, p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mul!(M, M, p) | |
M = mul!(M, p) |
# THIS FUNCTION NOT OFFICIALLY DOCUMENTED -- not intended for public use. | ||
function is_unimodular_given_det_mod_m(A::ZZMatrix, det_mod_m::Int, M::ZZRingElem; algorithm=:auto) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of a code comment which nobody will see, I suggest we start using a prefix like _
to indicate internal functions:
# THIS FUNCTION NOT OFFICIALLY DOCUMENTED -- not intended for public use. | |
function is_unimodular_given_det_mod_m(A::ZZMatrix, det_mod_m::Int, M::ZZRingElem; algorithm=:auto) | |
function _is_unimodular_given_det_mod_m(A::ZZMatrix, det_mod_m::Int, M::ZZRingElem; algorithm=:auto) |
Added new func
is_unimodular
for square integer matrices