Skip to content
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

Use GF as matrix element type? #15

Open
infogulch opened this issue Jul 10, 2021 · 6 comments
Open

Use GF as matrix element type? #15

infogulch opened this issue Jul 10, 2021 · 6 comments

Comments

@infogulch
Copy link

infogulch commented Jul 10, 2021

Hi! I'm trying to use GaloisFields as an element type in matrices, but I'm running into MethodErrors when using some of the stdlib matrix functions, some examples:

using GaloisFields
using LinearAlgebra
const F = @GaloisField/257ℤ

x = convert(Matrix{F},reshape(rand(F,4),2,2)) # random elements

det(x)   # MethodError: no method matching abs(::𝔽₂₅₇)
inv(x)   # MethodError: no method matching abs(::𝔽₂₅₇)
conj(x)  # MethodError: no method matching conj(::𝔽₂₅₇)

y = convert(Matrix{F},[1 0; 0 1]) # identity matrix elements

det(y)    # ok, returns 1
inv(y)    # MethodError: no method matching abs(::𝔽₂₅₇)
conj(y)   # MethodError: no method matching abs(::𝔽₂₅₇)

I did try the obvious defining abs:

abs(x::F) = x

But that didn't have any effect.

The stack trace of one of the abs errors is:

MethodError: no method matching abs(::𝔽₂₅₇)
Closest candidates are:
  abs(::Bool) at bool.jl:79
  abs(::Unsigned) at int.jl:169
  abs(::Signed) at int.jl:170
  ...

Stacktrace:
 [1] generic_lufact!(A::Matrix{𝔽₂₅₇}, ::Val{true}; check::Bool)
   @ LinearAlgebra /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/lu.jl:143
 [2] #lu!#134
   @ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/lu.jl:130 [inlined]
 [3] #lu#136
   @ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/lu.jl:273 [inlined]
 [4] det(A::Matrix{𝔽₂₅₇})
   @ LinearAlgebra /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/generic.jl:1560

And for conj:

MethodError: no method matching conj(::𝔽₂₅₇)
Closest candidates are:
  conj(::Union{Hermitian{T, S}, Symmetric{T, S}} where {T, S}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/symmetric.jl:368
  conj(::P) where P<:Polynomials.LaurentPolynomial at /opt/julia/packages/Polynomials/1aa8e/src/polynomials/LaurentPolynomial.jl:327
  conj(::P) where P<:Polynomials.AbstractPolynomial at /opt/julia/packages/Polynomials/1aa8e/src/common.jl:301
  ...

I must admit I'm new to both Julia and GF, so it's quite possible I'm doing something wrong. 😅

Thoughts?

@tkluck
Copy link
Owner

tkluck commented Jul 10, 2021

For now the best solution is to use LinearAlgebraX.jl for this use case.

I'll leave this bug open; maybe we can depend on LinearAlgebraX and add implementations like det(a::AbstractMatrix{<:GaloisField}) = detx(a).

I did try the obvious defining abs:

abs(x::F) = x

But that didn't have any effect.

FWIW for adding methods to functions from Base you have to qualify them:

Base.abs(x::F) = x

But in this case it will just complain about other methods next.

@infogulch
Copy link
Author

infogulch commented Jul 10, 2021

Wonderful, thank you for the direction and pointers!

maybe we can depend on LinearAlgebraX and add implementations

That sounds like it would be neat; though I might worry about adding a dependency for users that don't use that feature. I'm not sure I've ever encountered this in a software engineering context, multiple dispatch adds a lot of new capabilities to tie libraries together, but also brings some new problems to solve. I wonder if the community has a general strategy for this yet.

Perhaps a simple mention in the readme would be sufficient:

If you want to use GaloisFields with matrices look at the LinearAlgebraX ("Exact linear algebra functions") package.


So I tried to use LinearAlgebraX, but I ran into an issue where the result of the vector numeric equality binary operation results an array of GaloisField values instead of booleans:

using GaloisFields, LinearAlgebraX
const F = @GaloisField/257print(F(10) == 0)         # "false" -- ok
print([F(10) F(8)] .== 0) # 𝔽₂₅₇[0 0] -- ??? I expect [false false] instead
all([F(10) F(8)] .== 0)   # TypeError: non-boolean (𝔽₂₅₇) used in boolean context

This is used in LinearAlgebraX as part of the implementation of invx.

Any ideas why that happens?

@infogulch
Copy link
Author

infogulch commented Jul 11, 2021

Oh interesting, using the extended GF form works fine:

const G = @GaloisField! 2^8 β

print([β^10 β^8] .== 0)
all([β^10 β^8] .== 0)

Bool[0 0]
false

@tkluck
Copy link
Owner

tkluck commented Jul 11, 2021

@infogulch Thanks for reporting the bug about broadcasting ==. This is a bug in GaloisFields.jl and I'm opening #16 for you.

@infogulch
Copy link
Author

Great, thanks! If I find something else I'll put it in a new issue next time. 😄

@Gilles-Paul-Dubois
Copy link

This subject discussed here as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants