Zulip Chat Archive
Stream: Is there code for X?
Topic: Permutation to make a function monotone
Heather Macbeth (Nov 08 2021 at 03:46):
I thought that docs#finset.sort might do something like this, but apparently it outputs a list ... how can I get a permutation?
import data.fin.basic
variables {n : ℕ}
variables {α : Type*} [linear_order α]
def sort (f : fin n → α) : equiv.perm (fin n) := sorry
lemma monotone_sort (f : fin n → α) : monotone (f ∘ sort f) := sorry
Kyle Miller (Nov 08 2021 at 19:54):
There's docs#finset.order_iso_of_fin, which is close. I found a way to use it by constructing the graph of a function and sorting that lexicographically.
import data.fin.basic
import data.finset.sort
import order.lexicographic
variables {n : ℕ}
variables {α : Type*} [linear_order α]
def graph (f : fin n → α) : finset (lex α (fin n)) :=
finset.univ.image (λ i, (f i, i))
def graph.proj {f : fin n → α} : graph f → α := λ p, p.1.1
@[simp] lemma graph.card (f : fin n → α) : (graph f).card = n :=
begin
rw [graph, finset.card_image_of_injective],
simp,
rintros ⟨i, hi⟩ ⟨j, hj⟩,
simp,
end
/-- The induced map into the graph -/
def graph_equiv₁ (f : fin n → α) : fin n ≃ graph f :=
{ to_fun := λ i, ⟨(f i, i), by simp [graph]⟩,
inv_fun := λ p, p.1.2,
left_inv := λ i, by simp,
right_inv := λ ⟨⟨x, i⟩, h⟩, by simpa [graph] using h }
@[simp] lemma proj_equiv₁' (f : fin n → α) : graph.proj ∘ graph_equiv₁ f = f := rfl
/-- putting the graph in sorted order -/
def graph_equiv₂ (f : fin n → α) : fin n ≃o graph f :=
finset.order_iso_of_fin _ (by simp)
/-- The permutation that puts `f` in sorted order. -/
def sort (f : fin n → α) : equiv.perm (fin n) :=
(graph_equiv₂ f).to_equiv.trans (graph_equiv₁ f).symm
lemma self_comp_sort (f : fin n → α) : f ∘ sort f = graph.proj ∘ graph_equiv₂ f :=
begin
rw [sort],
nth_rewrite 0 [←proj_equiv₁' f],
change graph.proj ∘ ((graph_equiv₁ f) ∘ (graph_equiv₁ f).symm) ∘ (graph_equiv₂ f).to_equiv = _,
simp,
end
lemma monotone_sort (f : fin n → α) : monotone (f ∘ sort f) :=
begin
rw [self_comp_sort],
intros i j h,
simp,
have h' := (order_iso.le_iff_le (graph_equiv₂ f)).mpr h,
generalize hx : graph_equiv₂ f i = x,
generalize hy : graph_equiv₂ f j = y,
rw [hx, hy] at h',
obtain ⟨⟨x, I⟩, hI⟩ := x,
obtain ⟨⟨y, J⟩, hJ⟩ := y,
simp [graph.proj],
cases h',
apply le_of_lt, assumption,
refl,
end
Heather Macbeth (Nov 08 2021 at 20:08):
@Kyle Miller Wow, that's much more elaborate than I anticipated. Thank you! Could you PR it? (Or I could PR myself if you prefer.)
By the way, I was wondering whether the following would also work: use docs#multiset.map to consider the range of f
as a multiset in α
, sort this using docs#multiset.sort, and then somehow transfer back to give a sorting of fin n
. I've never used lists or multisets so I don't know how much work would be needed there.
Yury G. Kudryashov (Nov 08 2021 at 20:13):
Kyle used lex
to remember the index of each element while sorting on its value.
Kyle Miller (Nov 08 2021 at 20:44):
The lex
trick is to be able to distinguish each of the images of f
, which seems like the main difficulty with sort
. I'd originally tried doing things with lists directly, but it was extremely unpleasant.
Here's a commutative diagram that organizes what's going on in the construction:
Kyle Miller (Nov 08 2021 at 20:45):
Looking at this diagram more carefully, I realized I didn't take advantage of docs#monotone.comp. This can replace the last lemma:
lemma monotone_proj (f : fin n → α) : monotone (graph.proj : graph f → α) :=
begin
simp [graph.proj],
rintro ⟨⟨x, i⟩, hx⟩ ⟨⟨y, j⟩, hy⟩,
rintro (h|h),
simp,
exact le_of_lt ‹_›,
simp,
end
lemma monotone_sort (f : fin n → α) : monotone (f ∘ sort f) :=
begin
rw [self_comp_sort],
apply monotone.comp,
apply monotone_proj,
apply order_iso.monotone,
end
Kyle Miller (Nov 08 2021 at 20:48):
I'm also not sure how all of this should relate to docs#function.graph, which gives a relation. If you uncurry that relation and turn it into a set, its docs#set.to_finset would be equal to graph
.
Kyle Miller (Nov 08 2021 at 20:48):
@Heather Macbeth Would you mind PRing sort
and monotone_sort
?
Heather Macbeth (Nov 08 2021 at 20:49):
Sure, happy to (listing you as the author of course). Thanks again! By the way, the purpose here is to convert from a basis of eigenvectors to a basis of eigenvectors ordered by eigenvalue :)
Kevin Buzzard (Nov 08 2021 at 20:51):
what if the eigenvalues are complex ? ;-)
Heather Macbeth (Nov 08 2021 at 20:52):
Good thing they're not! :)
https://github.com/leanprover-community/mathlib/blob/d59f9ece9c74e1e04d1a506ea85fbfb9536a2af0/src/analysis/inner_product_space/spectrum.lean#L61
Yaël Dillies (Dec 16 2022 at 17:48):
It just occurred to me that this result is a corollary of #17932. Because a function f : α → β
monovaries with itself, the results in this PR give that there's some linear order on α
according to which f
is monotone. But then we can use the fact that perm α
acts transitively on linear_order α
to get the desired permutation.
Last updated: Dec 20 2023 at 11:08 UTC