-
Notifications
You must be signed in to change notification settings - Fork 297
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
[Merged by Bors] - feat(linear_algebra/orientation): composing with linear equivs and determinant #10737
Conversation
…terminant Add lemmas that composing an alternating map with a linear equiv using `comp_linear_map`, or composing a basis with a linear equiv using `basis.map`, produces the same orientation if and only if the determinant of that linear equiv is positive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you added the following instance:
/-- If two vectors are on the same ray then both scaled by the same action are also on the same
ray. -/
lemma same_ray.smul {S : Type*} [has_scalar S M] [smul_comm_class R S M]
{v₁ v₂ : M} (s : S) (h : same_ray R v₁ v₂) :
same_ray R (s • v₁) (s • v₂) :=
let ⟨r₁, r₂, hr₁, hr₂, h⟩ := h in
⟨r₁, r₂, hr₁, hr₂, by rw [smul_comm r₁ s v₁, smul_comm r₂ s v₂, h]⟩
/-- Any invertible action preserves the non-zeroness of rays. This is primarily of interest when
`G = units R` -/
instance {G} [group G] [nontrivial R] [distrib_mul_action G M] [smul_comm_class R G M] :
mul_action G (module.ray R M) :=
{ smul := λ r, quotient.map
(subtype.map ((•) r) $ λ a, (smul_ne_zero_iff_ne _).2) (λ a b, same_ray.smul _),
mul_smul := λ a b, quotient.ind $ begin
refine (λ m, congr_arg quotient.mk (subtype.ext _)),
exact mul_smul a b _,
end,
one_smul := quotient.ind $ begin
refine (λ m, congr_arg quotient.mk (subtype.ext _)),
exact one_smul _ _,
end }
@[simp] lemma smul_ray_of_ne_zero {G} [group G] [nontrivial R]
[distrib_mul_action G M] [smul_comm_class R G M] (g : G) (v : M) (hv) :
g • ray_of_ne_zero R v hv = ray_of_ne_zero R (g • v) ((smul_ne_zero_iff_ne _).2 hv) := rfl
and
-- do we have this?
def linear_equiv.det : (M ≃ₗ[R] M) →* units R :=
(units.map (linear_map.det : (M →ₗ[R] M) →* R)).comp
(linear_map.general_linear_group.general_linear_equiv R M).symm.to_monoid_hom
then you would be able to state
/-- Composing a basis with a linear equiv scales the orientation by the determinant. -/
lemma orientation_comp_linear_equiv_eq_iff_det_pos (e : basis ι R M) (f : M ≃ₗ[R] M) :
(e.map f).orientation = linear_equiv.det f • e.orientation :=
begin
which is likely a more useful statement as it's an equality.
I can see that action might be useful, and don't know what So I can see I should probably add |
How about I PR those suggestions in a separate PR, and then we come back to this one to see if they end up helping? |
Yes, that seems appropriate. I should also add: I wondered if my result for alternating maps could be deduced from that for bases (which has more general type class assumptions) in a way that makes the proof shorter, but while they are certainly related results, it seemed rather awkward to actually rewrite one into the other. |
Alright, I've made #10738. Your
Would follow from
|
Interestingly, with that PR, |
Here's the lemma orientation_comp_linear_equiv_eq (e : basis ι R M) (f : M ≃ₗ[R] M) :
(e.map f).orientation = linear_equiv.det f.symm • e.orientation :=
begin
simp_rw [basis.orientation, smul_ray_of_ne_zero, ray_eq_iff],
rw [(e.map f).det.eq_smul_basis_det e, e.det_map, ←linear_equiv.coe_coe, e.det_comp f.symm e,
e.det_self, mul_one, units.smul_def, linear_equiv.coe_det],
exact reflexive_same_ray R _ _,
end |
Feel free to push such |
src/linear_algebra/orientation.lean
Outdated
/-- Composing a basis with a linear equiv gives the same orientation if and only if the | ||
determinant is positive. -/ | ||
lemma orientation_comp_linear_equiv_eq_iff_det_pos (e : basis ι R M) (f : M ≃ₗ[R] M) : | ||
(e.map f).orientation = e.orientation ↔ 0 < (f : M →ₗ[R] M).det := | ||
by rw [orientation_map, units_inv_smul, units_smul_eq_self_iff, linear_equiv.coe_det] | ||
|
||
/-- Composing a basis with a linear equiv gives the negation of that orientation if and only if | ||
the determinant is negative. -/ | ||
lemma orientation_comp_linear_equiv_eq_neg_iff_det_neg (e : basis ι R M) (f : M ≃ₗ[R] M) : | ||
(e.map f).orientation = -e.orientation ↔ (f : M →ₗ[R] M).det < 0 := | ||
by rw [orientation_map, units_inv_smul, units_smul_eq_neg_iff, linear_equiv.coe_det] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsm28, do you think this lemma is still useful, now that it's just four rewrites?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure what version or versions will end up being most useful when I start working with concrete manipulations of bases to get them into the desired orientation (but also, different versions may end up being useful for different purposes).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep them then.
src/linear_algebra/orientation.lean
Outdated
-- TODO: does this generalize to an arbitrary orientation, not just `e.orientation`? | ||
lemma map_orientation_eq_det_inv_smul [nontrivial R] [is_domain R] (e : basis ι R M) | ||
(f : M ≃ₗ[R] M) : orientation.map ι f e.orientation = (f.det)⁻¹ • e.orientation := |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems extremely closely related to what I have as orientation_comp_linear_equiv_eq_iff_det_pos
, so I expect you'll want to refactor that in some way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm out of time for today, but I agree; those lemmas at the bottom of the file should probably be expressed in terms of the orientation.map
I added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, they should be proved in terms of lemmas for orientation.map
, I suppose, and start with one stated in terms of the units
action before deducing the ones about positive and negative determinants, but statements for alternating maps still make sense in their own right. All these groups of lemmas are proving related results about different APIs: what (basis.map
, orientation.map
, alternating_map.comp_linear_map
) do to an orientation, in terms of the determinant of the linear_equiv
involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now refactored so this is proved for an arbitrary orientation and the lemmas at the bottom of the file (special cases when the dimension is used to deduce the existence of a basis, essentially) are restated in terms of orientation.map
and deduced from this one.
src/linear_algebra/orientation.lean
Outdated
/-- An equivalence between modules implies an equivalence between orientations. -/ | ||
def orientation.map [nontrivial R] (e : M ≃ₗ[R] N) : orientation R M ι ≃ orientation R N ι := | ||
module.ray.map | ||
{ to_fun := λ f, f.comp_linear_map e.symm, | ||
inv_fun := λ g, g.comp_linear_map e, | ||
map_add' := λ _ _, rfl, | ||
map_smul' := λ _ _, rfl, | ||
left_inv := λ f, alternating_map.ext $ λ v, f.congr_arg $ funext $ λ i, e.symm_apply_apply _, | ||
right_inv := λ f, alternating_map.ext $ λ v, f.congr_arg $ funext $ λ i, e.apply_symm_apply _ } | ||
|
||
@[simp] lemma orientation.map_apply [nontrivial R] (e : M ≃ₗ[R] N) (v : alternating_map R M R ι) | ||
(hv : v ≠ 0) : | ||
orientation.map ι e (ray_of_ne_zero _ v hv) = ray_of_ne_zero _ (v.comp_linear_map e.symm) | ||
(mt (v.comp_linear_equiv_eq_zero_iff e.symm).mp hv) := rfl | ||
|
||
@[simp] lemma orientation.map_refl [nontrivial R] : | ||
(orientation.map ι $ linear_equiv.refl R M) = equiv.refl _ := | ||
equiv.ext $ module.ray.ind R $ λ _ _, begin | ||
dsimp, | ||
simp_rw alternating_map.comp_linear_map_id, | ||
end | ||
|
||
@[simp] lemma orientation.map_symm [nontrivial R] (e : M ≃ₗ[R] N) : | ||
(orientation.map ι e).symm = orientation.map ι e.symm := rfl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted this to #10815. I expect we probably want to extra alternating_map.dom_lcongr
from that too, but gitpod has given up on me so I can't try that.
🎉 Great news! Looks like all the dependencies have been resolved: 💡 To add or remove a dependency please update this issue/PR description. Brought to you by Dependent Issues (:robot: ). Happy coding! |
src/linear_algebra/orientation.lean
Outdated
lemma orientation_comp_linear_equiv_eq_iff_det_pos (f : alternating_map R M R ι) (hf : f ≠ 0) | ||
(g : M ≃ₗ[R] M) (h : fintype.card ι = finrank R M) : | ||
ray_of_ne_zero R (f.comp_linear_map ↑g) | ||
((not_iff_not.2 (f.comp_linear_equiv_eq_zero_iff g)).2 hf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LHS here is defeq equal to (ray_of_ne_zero R f hf).map g.symm
via orientation.map_apply
and linear_equiv.symm_symm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At which point both sides only refer to f
via ray_of_ne_zero R f hf
, so you can generalize to f : orientation R M ι
|
||
/-- The value of `orientation.map` when the index type has cardinality equal to the finite | ||
dimension, in terms of `f.det`. -/ | ||
lemma map_eq_det_inv_smul (x : orientation R M ι) (f : M ≃ₗ[R] M) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This lemma doesn't need a linear order, does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have a type class for non-linearly ordered fields, however. If enough of linear_algebra.finite_dimensional
gets generalized to module.free
, that should enable more general type class requirements here.
This looks great to me now, thanks - just worth double checking that the typeclasses aren't stronger than the proofs actually use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bors d+
✌️ jsm28 can now approve this pull request. To approve and merge a pull request, simply reply with |
Co-authored-by: Johan Commelin <johan@commelin.net>
bors r+ |
…terminant (#10737) Add lemmas that composing an alternating map with a linear equiv using `comp_linear_map`, or composing a basis with a linear equiv using `basis.map`, produces the same orientation if and only if the determinant of that linear equiv is positive. Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
Pull request successfully merged into master. Build succeeded: |
Add lemmas that composing an alternating map with a linear equiv using
comp_linear_map
, or composing a basis with a linear equiv usingbasis.map
, produces the same orientation if and only if thedeterminant of that linear equiv is positive.