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

feat(information_theory/linear_code): Define linear codes #16774

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

BoltonBailey
Copy link
Collaborator

@BoltonBailey BoltonBailey commented Oct 3, 2022

Add linear codes and defines the Reed-Solomon code.


Open in Gitpod

@BoltonBailey BoltonBailey changed the title feat(information_theory/block_code): Define linear codes feat(information_theory/linear_code): Define linear codes Oct 4, 2022
@BoltonBailey BoltonBailey added the awaiting-CI The author would like to see what CI has to say before doing more work. label Oct 4, 2022
Comment on lines +19 to +20

* `linear_code 𝓓 F`: The type of linear codes with domain `𝓓` over field `F`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `linear_code 𝓓 F`: The type of linear codes with domain `𝓓` over field `F`
* `linear_code 𝓓 F`: The type of linear codes with domain `𝓓` over field `F`

A linear error-correcting code, defined as a subspace of the vector space of functions from a
domain into a field.
-/
def linear_code (𝓓 F : Type) [fintype 𝓓] [field F] := submodule F ( 𝓓 -> F )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fintype assumption is unused.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which incidentally is to be expected - this is a problem I ran into. It's actually not really necessary that this be finite....

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that you're interested in matrices associated with the code, maybe it would be best to go with domain fin n

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for the general definition.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incidentally, you should use hamm (𝓓 -> F) as the type of the vectors: this is 𝓓 -> F equipped with the hamming norm as a metric.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I tried that but module F (hamming (λ (d : 𝓓), F)) failed to synthesize, presumably at some point I should go back and switch that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - it shouldn't have done, in theory. I would be grateful if you could try and replicate the issue in case it needs a patch.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe one should not hardcode hamm as the metric. Different types of codes use different metrics. E.g. your code may live in a matrix space, with distance the rank distance, i.e. dist(A,B)=rank(A-B).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is another reason I have hesitated before defining codes. I think it does want to be generalised ideally. It might want to be specific to integer-valued distances but this might not actually be necessary.

def length (C : linear_code 𝓓 F) : ℕ := fintype.card 𝓓

/-- The set of all valid codewords -/
def codewords (C : linear_code 𝓓 F) := C.carrier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this should be a set_like instance instead.

hamming distance of 0 from any nonzero element of the code.
-/
noncomputable def distance [decidable_eq F] (C : linear_code 𝓓 F) : ℕ :=
Inf (set.image (λ w : hamming (λ i : 𝓓, F), hamming_dist w 0) (C.codewords \ {0}))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the '' notation You can also use nat.find maybe.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been working on this for a little while (actually longer than I probably should have been). Well done for submitting it. I'm not sure this is the right approach to the minimum distance, however - at the very least, there's a number of theorems you'll want to show are true about it. I have a branch called infsep where I've been trying to define this concept rigourously.

Inf (set.image (λ w : hamming (λ i : 𝓓, F), hamming_dist w 0) (C.codewords \ {0}))

/-- The proportion of the code dimension to the size of the code -/
noncomputable def rate (C : linear_code 𝓓 F) : ℚ := rat.mk C.dimension C.length
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rat.mk has a better name in informal maths 😉

Suggested change
noncomputable def rate (C : linear_code 𝓓 F) : ℚ := rat.mk C.dimension C.length
noncomputable def rate (C : linear_code 𝓓 F) : ℚ := C.dimension / C.length

Comment on lines +117 to +120
intros a b ha hb,
rw set.mem_set_of at ha hb ⊢,
rcases ha with ⟨pa, hap⟩,
rcases hb with ⟨pb, hbp⟩,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
intros a b ha hb,
rw set.mem_set_of at ha hb ⊢,
rcases ha with ⟨pa, hap⟩,
rcases hb with ⟨pb, hbp⟩,
rintro a b ⟨pa, hap⟩ ⟨pb, hbp⟩,

@linesthatinterlace
Copy link
Collaborator

I feel a bit stupid because I've written versions of this same file a bunch of times in the last few months, I never submitted it, and now you actually did it - well done. However: my suspicion is that you might run into the same issues I did.

What this file lacks is many or any theorems. You're doing a lot of defining things - but every definition comes with a cost. What I want to see is some theorems proving (not necessarily complicated!) facts about these objects.

In addition - it doesn't make sense to me to define linear codes without first defining block codes, which was a sticking point for me. You're not really using the linearity that much in what you've done so far.

I would expect to see some mention of generating matrices and parity check matrices...

@linesthatinterlace
Copy link
Collaborator

I would be interested to see if you could base this off my infsep branch. That construction was intended for use in a PR like this - it was held up for a month by some PR issues.

@mathlib-dependent-issues-bot mathlib-dependent-issues-bot added blocked-by-other-PR This PR depends on another PR which is still in the queue. A bot manages this label via PR comment. and removed blocked-by-other-PR This PR depends on another PR which is still in the queue. A bot manages this label via PR comment. labels Oct 8, 2022
@mathlib-dependent-issues-bot
Copy link
Collaborator

/-- The repetition code, where all symbols in each codeword are the same. This is equivalent to a
Reed-Solomon code with max degree 0 -/
def repetition : linear_code 𝓓 F :=
{ carrier := {w | ∃ f : F, w = (λ x, f)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be much easier to prove as something like

linear_map.range { to_fun := function.const, map_add' := pi.const_add }

field.
-/
def reed_solomon (k : ℕ) (D : finset F) : linear_code D F :=
{ carrier := {w | ∃ p : polynomial F, p.nat_degree ≤ k ∧ w = (λ x, polynomial.eval x p)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to write this as the submodule.image of eval on the polynomials of degree-less- than-k.

@BoltonBailey BoltonBailey added the WIP Work in progress label Oct 19, 2022
@semorrison semorrison added the too-late This PR was ready too late for inclusion in mathlib3 label Jul 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-CI The author would like to see what CI has to say before doing more work. too-late This PR was ready too late for inclusion in mathlib3 WIP Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants