/- Copyright (c) 2024 Shengyang Xu. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Shengyang Xu -/ import Mathlib.Analysis.InnerProductSpace.PiL2 /-! # ConicCaratheodory ## Main results This file contains the proof of conic version of Caratheodory theorem. -/ open Finset variable {n : ℕ} {s : Finset ℕ} {V : ℕ → (EuclideanSpace ℝ (Fin n))} variable {x : EuclideanSpace ℝ (Fin n)} /- Nonnegative Coefficients -/ def quadrant : Set (ℕ → ℝ) := {x : ℕ → ℝ | ∀ i : ℕ, 0 ≤ x i} /- Restrict domain to Finset ℕ -/ def coe (s: Finset ℕ) : s → ℕ := fun i ↦ i /- Definition of cone with finite base -/ def cone (s : Finset ℕ) (V : ℕ → (EuclideanSpace ℝ (Fin n))) : Set (EuclideanSpace ℝ (Fin n)) := (fun x ↦ Finset.sum s (fun i => x i • V i)) '' quadrant /- An Alternative Proof of conic version of Caratheodory Theorem. Reference : https://courses.engr.illinois.edu/cs598csc/sp2010/Lectures/Lecture2.pdf Theorem 18. This lemma states that : If x is in the cone generated by Finset s whose elements are not linear independent, then it is in the cone generated by a strict subset of s -/ private lemma mem_conic_erase (s : Finset ℕ) (V : ℕ → (EuclideanSpace ℝ (Fin n))) (nidp : ¬LinearIndependent ℝ (V ∘ coe s)) (xincV : x ∈ cone s V) : ∃ y : s, x ∈ cone (s.erase y) V := by simp [cone, quadrant] at xincV rcases xincV with ⟨t, tin, xdecompose⟩ by_cases ht : ∃ i₀ : s, t i₀ = 0 · rcases ht with ⟨i₀, hti₀⟩ use i₀; simp [cone]; use t constructor · simp [quadrant, tin] · rw [← xdecompose, hti₀]; simp · have tpos : ∀ i : s, 0 < t i := by intro i; simp at ht; exact Ne.lt_of_le' (ht i i.prop) (tin i) let V₀ := fun i : ℕ ↦ t i • V i have nidp' : ¬LinearIndependent ℝ (V₀ ∘ coe s) := by obtain ⟨τ, k, ksum0, kextn0⟩ := not_linearIndependent_iff.1 nidp let k' := fun i : s ↦ k i / t i rw [not_linearIndependent_iff] use τ; use k'; constructor · rw [← ksum0]; simp [k', V₀, coe] apply Finset.sum_congr; simp intro i _; rw [smul_smul, div_mul_cancel₀]; linarith [tpos i] · obtain ⟨i₀, i₀in, ki₀ne0⟩ := kextn0 use i₀ ; use i₀in simp [k']; push_neg; use ki₀ne0; linarith [tpos i₀] have pos_case (k : s → ℝ) (ksum0 : (Finset.sum univ fun i ↦ k i • (V₀ ∘ coe s) i) = 0) (j : s) (kjpos : 0 < k j) : ∃ y : s, x ∈ cone (s.erase y) V := by have maxk : ∃ j₀ : s, ∀ j : s, k j ≤ k j₀ := by let k' := fun i : ℕ ↦ if hi : i ∈ s then k ⟨i, hi⟩ else 0 have sne : s.Nonempty := by use j; simp apply (s.exists_max_image k') at sne obtain ⟨j₀, j₀in, hj₀⟩ := sne; use ⟨j₀, j₀in⟩ intro j; specialize hj₀ j j.prop; simp [k', j₀in] at hj₀; apply hj₀ rcases maxk with ⟨j₀, kj₀max⟩ have kj₀pos : 0 < k j₀ := by linarith [kj₀max j] let β := fun i : ℕ => if hi : i ∈ s then (t i * k ⟨i, hi⟩) else 0 let α := fun i : ℕ => t i - β i / k j₀ have αpos : ∀ i : s, 0 ≤ α i := by intro i; simp [α, β]; rw [mul_div_assoc] apply mul_le_of_le_one_right; linarith [tpos i] rw [div_le_one]; linarith [kj₀max i]; linarith use j₀; simp [cone]; use α constructor · simp [quadrant]; intro i by_cases hi : i ∈ s · linarith [αpos ⟨i, hi⟩] · simp [α, hi, β]; linarith [tin i] · have hαj₀ : α j₀ = 0 := by field_simp [α, β] rw [hαj₀, ← xdecompose]; simp [α] have aux : (Finset.sum s fun x ↦ (t x - β x / k j₀) • V x) = (Finset.sum s fun x ↦ t x • V x) - (1 / k j₀) • (Finset.sum s fun x ↦ β x • V x) := by rw [Finset.smul_sum, ← Finset.sum_sub_distrib]; congr ext i j; rw [smul_smul, sub_smul]; field_simp rw [aux]; simp; right simp [V₀, coe] at ksum0; rw [← ksum0, ← Finset.sum_attach] congr; ext x l simp [β]; rw [← mul_assoc, mul_comm (t x) (k x)] obtain ⟨k, ksum0, kextn0⟩ := Fintype.not_linearIndependent_iff.1 nidp' rcases kextn0 with ⟨j, kjneq0⟩ by_cases kjpos: 0 < k j · apply pos_case k ksum0 j kjpos · let k' := fun i : s => - k i have k'sum0 : (Finset.sum univ fun i ↦ k' i • (V₀ ∘ coe s) i) = 0 := by simp at ksum0; simp [k', ksum0] have k'jpos : 0 < k' j := by simp [k']; simp at kjpos; exact Ne.lt_of_le kjneq0 kjpos apply pos_case k' k'sum0 j k'jpos theorem conic_Caratheodory (s : Finset ℕ) (V : ℕ → (EuclideanSpace ℝ (Fin n))): ∀ x ∈ cone s V, ∃ τ : Finset ℕ, (τ ⊆ s) ∧ (x ∈ cone τ V) ∧ (LinearIndependent ℝ (V ∘ coe τ)) ∧ (∀ σ : Finset ℕ, σ ⊆ s → x ∈ cone σ V → τ.card ≤ σ.card) := by intro x xin let idx := {τ : Finset ℕ | (τ ⊆ s) ∧ (x ∈ cone τ V)} have finite_idx : idx.Finite := by have finite_ps : Finite s.powerset := by apply Finset.finite_toSet have idx_sub_ps : idx ⊆ s.powerset := by intro τ τin simp [idx] at τin apply Finset.mem_powerset.2 τin.1 apply Set.Finite.subset _ idx_sub_ps apply finite_ps have ne_idx : Set.Nonempty idx := by use s; simp [idx, xin] let to_card : Finset ℕ → ℝ := fun x => x.card obtain ⟨τ, τin, τcardmin⟩ := idx.exists_min_image to_card finite_idx ne_idx use τ; simp [idx] at τin; use τin.1; use τin.2; constructor · by_contra nidp obtain ⟨y, xinerase⟩ := mem_conic_erase τ V nidp τin.2 let τ' := erase τ y specialize τcardmin τ'; simp [idx, τ'] at τcardmin have τ'subs : τ' ⊆ s := by simp [τ']; apply subset_trans _ τin.1 apply Finset.erase_subset specialize τcardmin τ'subs xinerase simp [to_card] at τcardmin absurd τcardmin; simp · intro σ σsubs; specialize τcardmin σ simp [idx, to_card] at τcardmin apply τcardmin σsubs