Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

[Merged by Bors] - feat(linear_algebra/matrix/circulant): add a file #9011

Closed
wants to merge 57 commits into from
Closed
Changes from 8 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
57b76d8
change
l534zhan Sep 4, 2021
f194203
change
l534zhan Sep 5, 2021
476ca9d
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 5, 2021
3513c0c
change
l534zhan Sep 5, 2021
ecdf441
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 6, 2021
962769f
change
l534zhan Sep 6, 2021
aca4d54
git push
l534zhan Sep 6, 2021
b2ad283
change
l534zhan Sep 6, 2021
84e5e8a
golf
jcommelin Sep 8, 2021
0f9631a
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 8, 2021
0fa2046
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 8, 2021
045cccf
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 8, 2021
f2b02ef
change
l534zhan Sep 8, 2021
57816ca
change
l534zhan Sep 8, 2021
b54d5df
chane
l534zhan Sep 8, 2021
d61ab55
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 10, 2021
8e7fb7c
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 10, 2021
7ad0bdb
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 10, 2021
539a881
change
l534zhan Sep 10, 2021
6337781
Merge branch 'cir_lz' of https://github.com/leanprover-community/math…
l534zhan Sep 10, 2021
73988d5
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
17ad2f0
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
67b8471
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
0016477
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
f28d2d5
change
l534zhan Sep 11, 2021
910bce6
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
0b7279c
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
025a269
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
99ec4e6
change
l534zhan Sep 11, 2021
68e4cea
Merge branch 'cir_lz' of https://github.com/leanprover-community/math…
l534zhan Sep 11, 2021
abbde3b
change
l534zhan Sep 11, 2021
a86d601
change
l534zhan Sep 11, 2021
84d3c7b
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
8142022
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 11, 2021
4bfb919
change
l534zhan Sep 11, 2021
c360edf
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 12, 2021
59f34f0
chagne
l534zhan Sep 12, 2021
94e98dd
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 12, 2021
3a10e74
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 12, 2021
30a5de6
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 12, 2021
aadc7fb
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
d89c1fe
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
651521c
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
b386251
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
2e1dc25
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
a3593b6
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
061cf74
change
l534zhan Sep 13, 2021
8d6b32c
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
f5a1bc5
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
aa3f7e5
change
l534zhan Sep 13, 2021
04cf6c0
change
l534zhan Sep 13, 2021
49eea71
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
5a3ce72
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
4da657c
change
l534zhan Sep 13, 2021
acb1470
Update src/linear_algebra/matrix/circulant.lean
l534zhan Sep 13, 2021
5b507d4
change
l534zhan Sep 13, 2021
911a3a0
change
l534zhan Sep 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 255 additions & 0 deletions src/linear_algebra/matrix/circulant.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
/-
Copyright (c) 2021 Lu-Ming Zhang. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Lu-Ming Zhang
-/
import linear_algebra.matrix.symmetric
import data.polynomial.monomial
import data.matrix.pequiv
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
import data.equiv.fin

/-!
# Circulant matrices

This file contains the definition and basic results about circulant matrices.
l534zhan marked this conversation as resolved.
Show resolved Hide resolved

## Main results

- `matrix.circulant`: introduce the definition of a circulant matrix
generated by a given vector `v : I → α`.

## Implementation notes

`fin.foo` is the `fin n` version of `foo`.
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
Namely, the index type of the circulant matrices in discussion is `fin n`.

## Tags

circulant, matrix
-/

variables {α β I J R : Type*} {n : ℕ}
l534zhan marked this conversation as resolved.
Show resolved Hide resolved

namespace matrix

open function
open_locale matrix big_operators

/-- Given the condition `[has_sub I]` and a vector `v : I → α`,
we define `circulant v` to be the circulant matrix generated by `v` of type `matrix I I α`. -/
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
def circulant [has_sub I] (v : I → α) : matrix I I α
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
| i j := v (i - j)

lemma circulant_col_zero_eq [add_group I] (v : I → α) :
(λ i, (circulant v) i 0) = v :=
by ext; simp [circulant]

lemma circulant_injective [add_group I] : injective (λ v : I → α, circulant v) :=
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
begin
intros v w h,
dsimp at h,
rw [← circulant_col_zero_eq v, ← circulant_col_zero_eq w, h]
end

lemma fin.circulant_injective : injective (λ v : fin n → α, circulant v) :=
begin
induction n with n ih,
{ tidy },
exact circulant_injective
end

lemma circulant_inj [add_group I] {v w : I → α} :
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
circulant v = circulant w ↔ v = w :=
circulant_injective.eq_iff

lemma fin.circulant_inj {v w : fin n → α} :
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
circulant v = circulant w ↔ v = w :=
fin.circulant_injective.eq_iff

lemma transpose_circulant [add_group I] (v : I → α) :
(circulant v)ᵀ = circulant (λ i, v (-i)) :=
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
by ext; simp [circulant]

lemma conj_transpose_circulant [has_star α] [add_group I] (v : I → α) :
(circulant v)ᴴ = circulant (star (λ i, v (-i))) :=
by ext; simp [circulant]

lemma fin.transpose_circulant (v : fin n → α) :
(circulant v)ᵀ = circulant (λ i, v (-i)) :=
begin
induction n with n ih, {tidy},
simp [transpose_circulant]
end

lemma fin.conj_transpose_circulant [has_star α] (v : fin n → α) :
(circulant v)ᴴ = circulant (star (λ i, v (-i))) :=
begin
induction n with n ih, {tidy},
simp [conj_transpose_circulant]
end

lemma map_circulant [has_sub I] (v : I → α) (f : α → β) :
(circulant v).map f = circulant (λ i, f (v i)) :=
by ext; simp [circulant]
Copy link
Member

Choose a reason for hiding this comment

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

I would guess you can replace all the proofs like this with

ext $ λ _ _, rfl

Copy link
Collaborator Author

@l534zhan l534zhan Sep 11, 2021

Choose a reason for hiding this comment

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

I don't think ext $ λ _ _, rfl will do for the most lemmas. Perhaps some variant.


lemma circulant_neg [has_neg α] [has_sub I] (v : I → α) :
circulant (- v) = - circulant v :=
by ext; simp [circulant]

lemma circulant_add [has_add α] [has_sub I] (v w : I → α) :
circulant (v + w) = circulant v + circulant w :=
by ext; simp [circulant]

lemma circulant_sub [has_sub α] [has_sub I] (v w : I → α) :
circulant (v - w) = circulant v - circulant w :=
by ext; simp [circulant]

lemma circulant_mul [semiring α] [fintype I] [add_comm_group I] (v w : I → α) :
circulant v ⬝ circulant w = circulant (mul_vec (circulant v) w) :=
begin
ext i j,
simp only [mul_apply, mul_vec, circulant, dot_product],
refine fintype.sum_equiv (equiv.sub_right j) _ _ _,
intro x,
simp only [equiv.sub_right_apply],
congr' 2,
abel
end
l534zhan marked this conversation as resolved.
Show resolved Hide resolved

lemma fin.circulant_mul [semiring α] (v w : fin n → α) :
circulant v ⬝ circulant w = circulant (mul_vec (circulant v) w) :=
begin
induction n with n ih, {refl},
exact circulant_mul v w,
end

/-- circulant matrices commute in multiplication under certain condations. -/
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
lemma circulant_mul_comm
[comm_semigroup α] [add_comm_monoid α] [fintype I] [add_comm_group I] (v w : I → α) :
circulant v ⬝ circulant w = circulant w ⬝ circulant v :=
begin
ext i j,
simp only [mul_apply, circulant, mul_comm],
refine fintype.sum_equiv ((equiv.sub_left i).trans (equiv.add_right j)) _ _ _,
intro x,
congr' 2,
{ simp },
{ simp only [equiv.coe_add_right, function.comp_app,
equiv.coe_trans, equiv.sub_left_apply],
abel }
end

lemma fin.circulant_mul_comm
[comm_semigroup α] [add_comm_monoid α] (v w : fin n → α) :
circulant v ⬝ circulant w = circulant w ⬝ circulant v :=
begin
induction n with n ih, {refl},
exact circulant_mul_comm v w,
end

/-- `k • circulant v` is another circulantcluant matrix `circulant (k • v)`. -/
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
lemma circulant_smul [has_sub I] [has_scalar R α] {k : R} {v : I → α} :
circulant (k • v) = k • circulant v :=
by {ext, simp [circulant]}

lemma circulant_zero [has_zero α] [has_sub I]:
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
circulant 0 = (0 : matrix I I α) :=
by ext; simp [circulant]

/-- The identity matrix is a circulant matrix. -/
lemma one_eq_circulant [has_zero α] [has_one α] [decidable_eq I] [add_group I]:
(1 : matrix I I α) = circulant (pi.single 0 1) :=
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
begin
ext,
simp only [circulant, one_apply, pi.single_apply],
congr' 1,
apply propext sub_eq_zero.symm,
end

/-- An alternative version of `one_eq_circulant`. -/
lemma one_eq_circulant' [has_zero α] [has_one α] [decidable_eq I] [add_group I]:
(1 : matrix I I α) = circulant (λ i, (1 : matrix I I α) i 0) :=
begin
convert one_eq_circulant,
ext,
simp [pi.single_apply, one_apply],
end

lemma fin.one_eq_circulant [has_zero α] [has_one α] :
(1 : matrix (fin n) (fin n) α) = circulant (λ i, ite (i.1 = 0) 1 0) :=
begin
induction n with n, {dec_trivial},
convert one_eq_circulant,
ext,
simp only [pi.single_apply],
congr' 1,
tidy
end

/-- For a one-ary predicate `p`, `p` applied to every entry of `circulant v` is true
if `p` applied to every entry of `v` is true. -/
lemma pred_circulant_entry_of_pred_vec_entry [has_sub I] {p : α → Prop} {v : I → α} :
(∀ k, p (v k)) → ∀ i j, p ((circulant v) i j) :=
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
begin
intros h i j,
simp [circulant],
exact h (i - j),
end

/-- Given a set `S`, every entry of `circulant v` is in `S` if every entry of `v` is in `S`. -/
lemma circulant_entry_in_of_vec_entry_in [has_sub I] {S : set α} {v : I → α} :
(∀ k, v k ∈ S) → ∀ i j, (circulant v) i j ∈ S :=
@pred_circulant_entry_of_pred_vec_entry α I _ S v
l534zhan marked this conversation as resolved.
Show resolved Hide resolved

/-- The circulant matrix `circulant v` is symmetric iff `∀ i j, v (j - i) = v (i - j)`. -/
lemma circulant_is_symm_ext_iff' [has_sub I] {v : I → α} :
(circulant v).is_symm ↔ ∀ i j, v (j - i) = v (i - j) :=
by simp [is_symm.ext_iff, circulant]

/-- The circulant matrix `circulant v` is symmetric iff `v (- i) = v i` if `[add_group I]`. -/
lemma circulant_is_symm_ext_iff [add_group I] {v : I → α} :
l534zhan marked this conversation as resolved.
Show resolved Hide resolved
(circulant v).is_symm ↔ ∀ i, v (- i) = v i :=
begin
rw [circulant_is_symm_ext_iff'],
split,
{ intros h i, convert h i 0; simp },
{ intros h i j, convert h (i - j), simp }
end

lemma fin.circulant_is_sym_ext_iff {v : fin n → α} :
(circulant v).is_symm ↔ ∀ i, v (- i) = v i :=
begin
induction n with n ih,
{ rw [circulant_is_symm_ext_iff'],
split;
{intros h i, have :=i.2, simp* at *} },
convert circulant_is_symm_ext_iff,
end

/-- If `circulant v` is symmetric, `∀ i j : I, v (j - i) = v (i - j)`. -/
lemma circulant_is_sym_apply' [has_sub I] {v : I → α} (h : (circulant v).is_symm) (i j : I) :
v (j - i) = v (i - j) :=
circulant_is_symm_ext_iff'.1 h i j

/-- If `circulant v` is symmetric, `∀ i j : I, v (- i) = v i`. -/
lemma circulant_is_sym_apply [add_group I] {v : I → α} (h : (circulant v).is_symm) (i : I) :
v (-i) = v i :=
circulant_is_symm_ext_iff.1 h i

lemma fin.circulant_is_sym_apply {v : fin n → α} (h : (circulant v).is_symm) (i : fin n) :
v (-i) = v i :=
fin.circulant_is_sym_ext_iff.1 h i

/-- The associated polynomial `(v 0) + (v 1) * X + ... + (v (n-1)) * X ^ (n-1)` to `circulant v`.-/
noncomputable
def circulant_poly [semiring α] (v : fin n → α) : polynomial α :=
∑ i : fin n, polynomial.monomial i (v i)
Copy link
Member

Choose a reason for hiding this comment

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

I'd be surprised if this doesn't already exist somewhere. At any rate, this belongs somewhere in one of the polynomial files, perhaps as polynomial_of_fin_coeffs

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So what do I need to do with this one now? @eric-wieser

Copy link
Member

@eric-wieser eric-wieser Sep 11, 2021

Choose a reason for hiding this comment

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

I think you should:

  • Ask zulip if it already exists
  • If not, move it to data/polynomial/coeff and call it polynomial_of_fin_coeffs

Copy link
Collaborator Author

@l534zhan l534zhan Sep 11, 2021

Choose a reason for hiding this comment

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

I have deleted the last two lemmas for now. We can do a new PR in the future concerning the algebra aspect or add back to this one if there is a simple answer.


/-- `circulant_perm n` is the cyclic permutation over `fin n`. -/
def circulant_perm : Π n, equiv.perm (fin n) := λ n, equiv.symm (fin_rotate n)

/-- `circulant_P α n` is the cyclic permutation matrix of order `n` with entries of type `α`. -/
def circulant_P (α) [has_zero α] [has_one α] (n : ℕ) : matrix (fin n) (fin n) α :=
(circulant_perm n).to_pequiv.to_matrix

end matrix