|
| 1 | +/- |
| 2 | +Copyright (c) 2026 Weiyi Wang. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Weiyi Wang |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.Analysis.InnerProductSpace.Adjoint |
| 9 | +public import Mathlib.Analysis.InnerProductSpace.GramMatrix |
| 10 | + |
| 11 | +/-! |
| 12 | +# Normed determinant of a linear map |
| 13 | +
|
| 14 | +Given a rectangular matrix $T$, it is common to talk about $\sqrt{det(T^{H}T)}$, where $T^{H}$ is |
| 15 | +the conjugate transpose of $T$, as a generalization to the determinant of a square matrix. It is the |
| 16 | +$m$-dimensional volume factor for $\mathbb{R}^m \to \mathbb{R}^n$. It is given various names in |
| 17 | +literature: |
| 18 | +* "Jacobian" (definition 3.4 of [lawrenceronald2025]), in the context of volume factor |
| 19 | + for non-linear map. However, we choose to reserve this name for the matrix consists of |
| 20 | + derivatives. |
| 21 | +* "Gram determinant", which is already used by `Matrix.gram`, and it is often referring to the |
| 22 | + $det(T^{H}T)$ without the square root. |
| 23 | +* "Nonnegative determinant" (definition 1 of [haruoyoshiohidetoki2006]). |
| 24 | +
|
| 25 | +Without a standardized name, we give a descriptive name `LinearMap.normDet` to reflect its |
| 26 | +definition and show that it is a generalization of `‖(f : LinearMap 𝕜 U U).det‖` |
| 27 | +(See `LinearMap.normDet_eq_norm_det`). We also construct this on linear maps between inner product |
| 28 | +spaces instead of matrices, and allow the codomain to have infinite dimension. |
| 29 | +
|
| 30 | +## Main definition |
| 31 | +* `LinearMap.normDet` : the norm determinant of a linear map. |
| 32 | +
|
| 33 | +## Main result |
| 34 | +* `ContinuousLinearMap.normDet_sq` and `LinearMap.normDet_sq`: The square of `f.normDet` |
| 35 | + equals to the determinant of `f.adjoint ∘ₗ f`. |
| 36 | +
|
| 37 | +## TODO |
| 38 | +
|
| 39 | +Show that `LinearMap.normDet` is the product of all singular values of the map. |
| 40 | +-/ |
| 41 | + |
| 42 | +public section |
| 43 | + |
| 44 | +namespace LinearMap |
| 45 | + |
| 46 | +variable {𝕜 U V : Type*} [RCLike 𝕜] [NormedAddCommGroup U] [InnerProductSpace 𝕜 U] |
| 47 | + [FiniteDimensional 𝕜 U] [NormedAddCommGroup V] [InnerProductSpace 𝕜 V] |
| 48 | + |
| 49 | +open Classical in |
| 50 | +/-- |
| 51 | +The norm determinant of a linear map `f : U →ₗ[𝕜] V` is defined as the norm of the determinant of |
| 52 | +the square matrix from `U →ₗ[𝕜] f.range` using a pair of orthonormal basis of equal dimensions. |
| 53 | +(See `LinearMap.normDet_eq` for using arbitrary orthonormal basis) |
| 54 | +
|
| 55 | +If such basis doesn't exist (i.e. the map is not injective), the norm determinant is zero. |
| 56 | +(See `LinearMap.normDet_eq_zero_iff_ker_ne_bot`) |
| 57 | +-/ |
| 58 | +noncomputable def normDet (f : U →ₗ[𝕜] V) : ℝ := |
| 59 | + if h : Nonempty (OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range) then |
| 60 | + ‖(f.rangeRestrict.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis h.some.toBasis).det‖ |
| 61 | + else |
| 62 | + 0 |
| 63 | + |
| 64 | +theorem normDet_nonneg (f : U →ₗ[𝕜] V) : 0 ≤ f.normDet := by |
| 65 | + unfold normDet |
| 66 | + split <;> simp |
| 67 | + |
| 68 | +/-- |
| 69 | +`LinearMap.normDet` is well-defined under any pair of orthonormal basis. |
| 70 | +-/ |
| 71 | +theorem normDet_eq {ι : Type*} [Fintype ι] [DecidableEq ι] (f : U →ₗ[𝕜] V) |
| 72 | + (bu : OrthonormalBasis ι 𝕜 U) (bv : OrthonormalBasis ι 𝕜 f.range) : |
| 73 | + f.normDet = ‖(f.rangeRestrict.toMatrix bu.toBasis bv.toBasis).det‖ := by |
| 74 | + have hrank : Module.finrank 𝕜 U = Module.finrank 𝕜 f.range := by |
| 75 | + rw [Module.finrank_eq_nat_card_basis bu.toBasis, Module.finrank_eq_nat_card_basis bv.toBasis] |
| 76 | + have h : Nonempty (OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range) := by |
| 77 | + rw [hrank] |
| 78 | + exact ⟨stdOrthonormalBasis 𝕜 f.range⟩ |
| 79 | + simp only [normDet, h, ↓reduceDIte] |
| 80 | + rw [← basis_toMatrix_mul_linearMap_toMatrix_mul_basis_toMatrix (stdOrthonormalBasis 𝕜 U).toBasis |
| 81 | + bu.toBasis h.some.toBasis bv.toBasis] |
| 82 | + have h1 : bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis * |
| 83 | + (stdOrthonormalBasis 𝕜 U).toBasis.toMatrix bu.toBasis = 1 := |
| 84 | + Module.Basis.toMatrix_mul_toMatrix_flip _ _ |
| 85 | + have h2 : (stdOrthonormalBasis 𝕜 U).toBasis.toMatrix bu.toBasis * |
| 86 | + bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis = 1 := |
| 87 | + Module.Basis.toMatrix_mul_toMatrix_flip _ _ |
| 88 | + rw [← Matrix.det_comm' h1 h2, ← Matrix.mul_assoc, Matrix.det_mul, norm_mul] |
| 89 | + suffices ‖(bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis * |
| 90 | + h.some.toBasis.toMatrix ⇑bv.toBasis).det‖ = 1 by |
| 91 | + rw [this] |
| 92 | + simp |
| 93 | + apply CStarRing.norm_of_mem_unitary |
| 94 | + apply Matrix.det_of_mem_unitary |
| 95 | + rw [Matrix.mem_unitaryGroup_iff, Matrix.star_eq_conjTranspose, Matrix.conjTranspose_mul, |
| 96 | + ← Matrix.mul_assoc, Matrix.mul_assoc (bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis)] |
| 97 | + simp |
| 98 | + |
| 99 | +/-- |
| 100 | +`LinearMap.normDet` vanishes iff the map is not injective. |
| 101 | +-/ |
| 102 | +theorem normDet_eq_zero_iff_ker_ne_bot (f : U →ₗ[𝕜] V) : |
| 103 | + f.normDet = 0 ↔ f.ker ≠ ⊥ where |
| 104 | + mp h := by |
| 105 | + contrapose! h |
| 106 | + let g : U ≃ₗ[𝕜] f.range := LinearEquiv.ofBijective f.rangeRestrict |
| 107 | + ⟨by simpa using ker_eq_bot.mp h, f.surjective_rangeRestrict⟩ |
| 108 | + let bu := stdOrthonormalBasis 𝕜 U |
| 109 | + let bv := g.finrank_eq.symm ▸ stdOrthonormalBasis 𝕜 f.range |
| 110 | + rw [f.normDet_eq bu bv, norm_eq_zero.ne] |
| 111 | + suffices (f.rangeRestrict.adjoint.toMatrix bv.toBasis bu.toBasis).det * |
| 112 | + (f.rangeRestrict.toMatrix bu.toBasis bv.toBasis).det ≠ 0 by |
| 113 | + simpa [toMatrix_adjoint, Matrix.det_conjTranspose] using this |
| 114 | + simpa [← Matrix.det_mul, ← LinearMap.toMatrix_comp, det_eq_zero_iff_ker_ne_bot, |
| 115 | + LinearMap.ker_adjoint_comp_self] using h |
| 116 | + mpr h := by |
| 117 | + suffices ¬ Nonempty (OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range) by |
| 118 | + simp [normDet, this] |
| 119 | + contrapose! h |
| 120 | + obtain ⟨b⟩ := h |
| 121 | + have hrank : Module.finrank 𝕜 f.range = Module.finrank 𝕜 U := by |
| 122 | + simpa using Module.finrank_eq_card_basis b.toBasis |
| 123 | + simpa [hrank] using f.finrank_range_add_finrank_ker |
| 124 | + |
| 125 | +/-- |
| 126 | +`LinearMap.normDet` equals to the norm of `LinearMap.det` for an endomorphism. |
| 127 | +-/ |
| 128 | +theorem normDet_eq_norm_det (f : U →ₗ[𝕜] U) : f.normDet = ‖f.det‖ := by |
| 129 | + by_cases h : f.range = ⊤ |
| 130 | + · let bv : OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range := |
| 131 | + (stdOrthonormalBasis 𝕜 U).map (LinearIsometryEquiv.ofTop U _ h).symm |
| 132 | + rw [normDet_eq f (stdOrthonormalBasis 𝕜 U) bv] |
| 133 | + simp [bv, toMatrix_map_right] |
| 134 | + · have hb : ¬ Nonempty (OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range) := by |
| 135 | + contrapose! h |
| 136 | + obtain ⟨b⟩ := h |
| 137 | + apply Submodule.eq_top_of_finrank_eq |
| 138 | + conv_lhs => rw [Module.finrank_eq_nat_card_basis b.toBasis] |
| 139 | + conv_rhs => rw [Module.finrank_eq_nat_card_basis (stdOrthonormalBasis 𝕜 U).toBasis] |
| 140 | + suffices f.det = 0 by |
| 141 | + simp [this, normDet, hb] |
| 142 | + simpa [det_eq_zero_iff_ker_ne_bot] using ker_eq_bot_iff_range_eq_top.not.mpr h |
| 143 | + |
| 144 | +/-- |
| 145 | +`LinearMap.normDet` of a linear isometry is 1. |
| 146 | +-/ |
| 147 | +theorem _root_.LinearIsometry.normDet_eq_one (f : U →ₗᵢ[𝕜] V) : f.toLinearMap.normDet = 1 := by |
| 148 | + have hrank : Module.finrank 𝕜 U = Module.finrank 𝕜 f.range := |
| 149 | + f.equivRange.toLinearEquiv.finrank_eq |
| 150 | + let b := (stdOrthonormalBasis 𝕜 f.toLinearMap.range) |
| 151 | + rw [← hrank] at b |
| 152 | + rw [normDet_eq _ (stdOrthonormalBasis 𝕜 U) b] |
| 153 | + apply CStarRing.norm_of_mem_unitary |
| 154 | + exact Matrix.det_of_mem_unitary <| (f.equivRange).toMatrix_mem_unitaryGroup _ _ |
| 155 | + |
| 156 | +set_option backward.isDefEq.respectTransparency false in |
| 157 | +/-- |
| 158 | +The square of `f.normDet` equals to the determinant of `f.adjoint ∘L f`. |
| 159 | +-/ |
| 160 | +theorem _root_.ContinuousLinearMap.normDet_sq [CompleteSpace V] (f : U →L[𝕜] V) : |
| 161 | + haveI : CompleteSpace U := FiniteDimensional.complete 𝕜 U |
| 162 | + ↑(f.normDet ^ 2) = (f.adjoint ∘L f).det := by |
| 163 | + have : CompleteSpace U := FiniteDimensional.complete 𝕜 U |
| 164 | + have : CompleteSpace f.range := FiniteDimensional.complete 𝕜 f.range |
| 165 | + let bu := stdOrthonormalBasis 𝕜 U |
| 166 | + classical |
| 167 | + by_cases hrank : Module.finrank 𝕜 U = Module.finrank 𝕜 f.range |
| 168 | + · let b : OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range := |
| 169 | + (stdOrthonormalBasis 𝕜 f.range).reindex (by |
| 170 | + rw [← hrank, Module.finrank_eq_card_basis bu.toBasis]) |
| 171 | + have hf : f = f.range.subtypeₗᵢ.toContinuousLinearMap ∘L f.rangeRestrict := rfl |
| 172 | + conv_rhs => rw [hf] |
| 173 | + rw [ContinuousLinearMap.adjoint_comp, ← ContinuousLinearMap.comp_assoc, |
| 174 | + ContinuousLinearMap.comp_assoc (ContinuousLinearMap.adjoint _)] |
| 175 | + suffices f.range.subtypeₗᵢ.toContinuousLinearMap.adjoint ∘L |
| 176 | + f.range.subtypeₗᵢ.toContinuousLinearMap = ContinuousLinearMap.id 𝕜 _ by |
| 177 | + rw [this, ContinuousLinearMap.comp_id, ContinuousLinearMap.det, ContinuousLinearMap.coe_comp, |
| 178 | + ← det_toMatrix bu.toBasis, toMatrix_comp bu.toBasis b.toBasis bu.toBasis] |
| 179 | + rw [show (ContinuousLinearMap.adjoint f.rangeRestrict).toLinearMap = |
| 180 | + f.rangeRestrict.toLinearMap.adjoint by rfl] |
| 181 | + rw [toMatrix_adjoint] |
| 182 | + simp [f.toLinearMap.normDet_eq bu b, RCLike.conj_mul] |
| 183 | + exact f.range.subtypeₗᵢ.adjoint_comp_self |
| 184 | + · have hb : ¬ Nonempty (OrthonormalBasis (Fin (Module.finrank 𝕜 U)) 𝕜 f.range) := by |
| 185 | + contrapose! hrank with h |
| 186 | + obtain ⟨bv⟩ := h |
| 187 | + rw [Module.finrank_eq_card_basis bu.toBasis, Module.finrank_eq_card_basis bv.toBasis] |
| 188 | + trans 0 |
| 189 | + · simp [normDet, hb] |
| 190 | + symm |
| 191 | + rw [det_eq_zero_iff_ker_ne_bot, ContinuousLinearMap.ker_adjoint_comp_self] |
| 192 | + contrapose! hrank |
| 193 | + exact (finrank_range_of_inj <| ker_eq_bot.mp hrank).symm |
| 194 | + |
| 195 | +/-- |
| 196 | +The square of `f.normDet` equals to the determinant of `f.adjoint ∘ₗ f` when the codomain is finite |
| 197 | +dimensional. |
| 198 | +-/ |
| 199 | +theorem normDet_sq [FiniteDimensional 𝕜 V] (f : U →ₗ[𝕜] V) : |
| 200 | + ↑(f.normDet ^ 2) = (f.adjoint ∘ₗ f).det := by |
| 201 | + have : CompleteSpace V := FiniteDimensional.complete 𝕜 V |
| 202 | + exact f.toContinuousLinearMap.normDet_sq |
| 203 | + |
| 204 | +end LinearMap |
0 commit comments