Closed arghhhh closed 2 years ago
Could you please submit a Pull Request with these changes so that people can easily test them out?
It would also be great to include some tests, for example with your ModN
type.
OK. I am new to this (never contributed to any open source project). There are really two issues here - one is relatively trivial uses of zero() and one() instead of 0 and 1 literals and the use of abs(zero(T)) instead of real(zero(T)) to avoid having to define real() which might not make sense for some matrix eltypes (eg for modulo{polynomial} ).
I put an example derived from the ModInt example in the Julia source here: https://gist.github.com/arghhhh/abdb8b6d28039f683f5287e124903670 and will submit a pull request shortly.
The second issue is how to control pivoting in lufact. It seems to me that there could be three options here:
The current implementation uses Val{false} and Val{true} to choose between 1. and 3. Adding 2. would require a bigger discussion.
It would be great with the other pivoting option as well. The reason for the current design is that we try to use the same API for LU and QR. The pivoted QR returns a different type which is the reason why we use Val
s here. For LU, we use the same type so Val
is not really needed but we should probably be consistent across LU and QR. We could consider adding pivoting types instead or use symbols instead of Booleans in the Val
, e.g. Pivot{:anyrow}
, Val{:maxrow}
, or NormCol
. I'm not super happy with any of these. Thoughts?
I had wondered why the Val{}
argument had been used. I was thinking that using a symbol instead of the Bool would work - but I only realized this needed to be a separate option after my original issue submission. My original proposal hijacked Pivot=Val{false}
to mean pivot on !iszero
.
I'm not sure how to proceed. I'm new to contributing to Julia, so it was exciting(!) to see my PR make progress - but I haven't actually solved my original problem. My motivation is that I'm learning about finite fields and abstract algebra to enable understanding and implementation of error control coding - similar to https://github.com/andrewcooke/IntModN.jl
I've made a minimal Mod{N} with only the operations required to be a field. I needed to make a few modifications to the linalg code to get A \ b to work for a square matrix A with Mod{N} as the element type.
Specifically: In a few places, a literal "0" is used instead of zero( .. ). I'd rather not add a conversion / promotion. It should work without this. In one place "real( .. )" is used to initialize a variable that will hold the result of abs( .. )
If I turn off pivoting to reduce the requirements on my type further (so I don't need < or abs) then it doesn't work due to a SingularException error. I added a search for the first non-zero index and pivot on that - so its now pivoting, but without the requirement to have "abs" and "<". I use this to line to turn off pivoting for matrices of my type Mod{N}:
import Base: lufact lufact{N}(A::AbstractMatrix{Mod{N}}, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{false}) = lufact!(copy(A), pivot)
Below is a complete diff of my changes relative to v0.6.0-rc2.
Its pretty amazing that you can do this in Julia. It'd be great if we could fix these minor issues. I'm not a mathematician, so I'm not completely sure about the pivoting on non-zero element, but it worked for me on my one(!) test case.