Skip to content

Commit

Permalink
feat: port Analysis.Calculus.Deriv.Inv (#4443)
Browse files Browse the repository at this point in the history
Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com>
  • Loading branch information
urkud and Parcly-Taxel committed May 30, 2023
1 parent 5c0483b commit a206a3e
Show file tree
Hide file tree
Showing 2 changed files with 247 additions and 0 deletions.
1 change: 1 addition & 0 deletions Mathlib.lean
Expand Up @@ -419,6 +419,7 @@ import Mathlib.Analysis.Calculus.Darboux
import Mathlib.Analysis.Calculus.Deriv.Add
import Mathlib.Analysis.Calculus.Deriv.Basic
import Mathlib.Analysis.Calculus.Deriv.Comp
import Mathlib.Analysis.Calculus.Deriv.Inv
import Mathlib.Analysis.Calculus.Deriv.Inverse
import Mathlib.Analysis.Calculus.Deriv.Linear
import Mathlib.Analysis.Calculus.Deriv.Mul
Expand Down
246 changes: 246 additions & 0 deletions Mathlib/Analysis/Calculus/Deriv/Inv.lean
@@ -0,0 +1,246 @@
/-
Copyright (c) 2023 SΓ©bastien GouΓ«zel. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: SΓ©bastien GouΓ«zel, Yury Kudryashov
! This file was ported from Lean 3 source module analysis.calculus.deriv.inv
! leanprover-community/mathlib commit 3bce8d800a6f2b8f63fe1e588fd76a9ff4adcebe
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Analysis.Calculus.Deriv.Mul
import Mathlib.Analysis.Calculus.Deriv.Comp

/-!
# Derivatives of `x ↦ x⁻¹` and `f x / g x`
In this file we prove `(x⁻¹)' = -1 / x ^ 2`, `((f x)⁻¹)' = -f' x / (f x) ^ 2`, and
`(f x / g x)' = (f' x * g x - f x * g' x) / (g x) ^ 2` for different notions of derivative.
For a more detailed overview of one-dimensional derivatives in mathlib, see the module docstring of
`Analysis/Calculus/Deriv/Basic`.
## Keywords
derivative
-/


universe u v w

open Classical Topology BigOperators Filter ENNReal

open Filter Asymptotics Set

open ContinuousLinearMap (smulRight smulRight_one_eq_iff)

variable {π•œ : Type u} [NontriviallyNormedField π•œ]

variable {F : Type v} [NormedAddCommGroup F] [NormedSpace π•œ F]

variable {E : Type w} [NormedAddCommGroup E] [NormedSpace π•œ E]

variable {f fβ‚€ f₁ g : π•œ β†’ F}

variable {f' fβ‚€' f₁' g' : F}

variable {x : π•œ}

variable {s t : Set π•œ}

variable {L : Filter π•œ}

section Inverse

/-! ### Derivative of `x ↦ x⁻¹` -/

theorem hasStrictDerivAt_inv (hx : x β‰  0) : HasStrictDerivAt Inv.inv (-(x ^ 2)⁻¹) x := by
suffices
(fun p : π•œ Γ— π•œ => (p.1 - p.2) * ((x * x)⁻¹ - (p.1 * p.2)⁻¹)) =o[𝓝 (x, x)] fun p =>
(p.1 - p.2) * 1 by
refine' this.congr' _ (eventually_of_forall fun _ => mul_one _)
refine' Eventually.mono ((isOpen_ne.prod isOpen_ne).mem_nhds ⟨hx, hx⟩) _
rintro ⟨y, z⟩ ⟨hy, hz⟩
simp only [mem_setOf_eq] at hy hz
-- hy : y β‰  0, hz : z β‰  0
field_simp [hx, hy, hz]
ring
refine' (isBigO_refl (fun p : π•œ Γ— π•œ => p.1 - p.2) _).mul_isLittleO ((isLittleO_one_iff π•œ).2 _)
rw [← sub_self (x * x)⁻¹]
exact tendsto_const_nhds.sub ((continuous_mul.tendsto (x, x)).invβ‚€ <| mul_ne_zero hx hx)
#align has_strict_deriv_at_inv hasStrictDerivAt_inv

theorem hasDerivAt_inv (x_ne_zero : x β‰  0) : HasDerivAt (fun y => y⁻¹) (-(x ^ 2)⁻¹) x :=
(hasStrictDerivAt_inv x_ne_zero).hasDerivAt
#align has_deriv_at_inv hasDerivAt_inv

theorem hasDerivWithinAt_inv (x_ne_zero : x β‰  0) (s : Set π•œ) :
HasDerivWithinAt (fun x => x⁻¹) (-(x ^ 2)⁻¹) s x :=
(hasDerivAt_inv x_ne_zero).hasDerivWithinAt
#align has_deriv_within_at_inv hasDerivWithinAt_inv

theorem differentiableAt_inv : DifferentiableAt π•œ (fun x => x⁻¹) x ↔ x β‰  0 :=
⟨fun H => NormedField.continuousAt_inv.1 H.continuousAt, fun H =>
(hasDerivAt_inv H).differentiableAt⟩
#align differentiable_at_inv differentiableAt_inv

theorem differentiableWithinAt_inv (x_ne_zero : x β‰  0) :
DifferentiableWithinAt π•œ (fun x => x⁻¹) s x :=
(differentiableAt_inv.2 x_ne_zero).differentiableWithinAt
#align differentiable_within_at_inv differentiableWithinAt_inv

theorem differentiableOn_inv : DifferentiableOn π•œ (fun x : π•œ => x⁻¹) { x | x β‰  0 } := fun _x hx =>
differentiableWithinAt_inv hx
#align differentiable_on_inv differentiableOn_inv

theorem deriv_inv : deriv (fun x => x⁻¹) x = -(x ^ 2)⁻¹ := by
rcases eq_or_ne x 0 with (rfl | hne)
Β· simp [deriv_zero_of_not_differentiableAt (mt differentiableAt_inv.1 (not_not.2 rfl))]
Β· exact (hasDerivAt_inv hne).deriv
#align deriv_inv deriv_inv

@[simp]
theorem deriv_inv' : (deriv fun x : π•œ => x⁻¹) = fun x => -(x ^ 2)⁻¹ :=
funext fun _ => deriv_inv
#align deriv_inv' deriv_inv'

theorem derivWithin_inv (x_ne_zero : x β‰  0) (hxs : UniqueDiffWithinAt π•œ s x) :
derivWithin (fun x => x⁻¹) s x = -(x ^ 2)⁻¹ := by
rw [DifferentiableAt.derivWithin (differentiableAt_inv.2 x_ne_zero) hxs]
exact deriv_inv
#align deriv_within_inv derivWithin_inv

theorem hasFDerivAt_inv (x_ne_zero : x β‰  0) :
HasFDerivAt (fun x => x⁻¹) (smulRight (1 : π•œ β†’L[π•œ] π•œ) (-(x ^ 2)⁻¹) : π•œ β†’L[π•œ] π•œ) x :=
hasDerivAt_inv x_ne_zero
#align has_fderiv_at_inv hasFDerivAt_inv

theorem hasFDerivWithinAt_inv (x_ne_zero : x β‰  0) :
HasFDerivWithinAt (fun x => x⁻¹) (smulRight (1 : π•œ β†’L[π•œ] π•œ) (-(x ^ 2)⁻¹) : π•œ β†’L[π•œ] π•œ) s x :=
(hasFDerivAt_inv x_ne_zero).hasFDerivWithinAt
#align has_fderiv_within_at_inv hasFDerivWithinAt_inv

theorem fderiv_inv : fderiv π•œ (fun x => x⁻¹) x = smulRight (1 : π•œ β†’L[π•œ] π•œ) (-(x ^ 2)⁻¹) := by
rw [← deriv_fderiv, deriv_inv]
#align fderiv_inv fderiv_inv

theorem fderivWithin_inv (x_ne_zero : x β‰  0) (hxs : UniqueDiffWithinAt π•œ s x) :
fderivWithin π•œ (fun x => x⁻¹) s x = smulRight (1 : π•œ β†’L[π•œ] π•œ) (-(x ^ 2)⁻¹) := by
rw [DifferentiableAt.fderivWithin (differentiableAt_inv.2 x_ne_zero) hxs]
exact fderiv_inv
#align fderiv_within_inv fderivWithin_inv

variable {c : π•œ β†’ π•œ} {h : E β†’ π•œ} {c' : π•œ} {z : E} {S : Set E}

theorem HasDerivWithinAt.inv (hc : HasDerivWithinAt c c' s x) (hx : c x β‰  0) :
HasDerivWithinAt (fun y => (c y)⁻¹) (-c' / c x ^ 2) s x := by
convert (hasDerivAt_inv hx).comp_hasDerivWithinAt x hc using 1
field_simp
#align has_deriv_within_at.inv HasDerivWithinAt.inv

theorem HasDerivAt.inv (hc : HasDerivAt c c' x) (hx : c x β‰  0) :
HasDerivAt (fun y => (c y)⁻¹) (-c' / c x ^ 2) x := by
rw [← hasDerivWithinAt_univ] at *
exact hc.inv hx
#align has_deriv_at.inv HasDerivAt.inv

theorem DifferentiableWithinAt.inv (hf : DifferentiableWithinAt π•œ h S z) (hz : h z β‰  0) :
DifferentiableWithinAt π•œ (fun x => (h x)⁻¹) S z :=
(differentiableAt_inv.mpr hz).comp_differentiableWithinAt z hf
#align differentiable_within_at.inv DifferentiableWithinAt.inv

@[simp]
theorem DifferentiableAt.inv (hf : DifferentiableAt π•œ h z) (hz : h z β‰  0) :
DifferentiableAt π•œ (fun x => (h x)⁻¹) z :=
(differentiableAt_inv.mpr hz).comp z hf
#align differentiable_at.inv DifferentiableAt.inv

theorem DifferentiableOn.inv (hf : DifferentiableOn π•œ h S) (hz : βˆ€ x ∈ S, h x β‰  0) :
DifferentiableOn π•œ (fun x => (h x)⁻¹) S := fun x h => (hf x h).inv (hz x h)
#align differentiable_on.inv DifferentiableOn.inv

@[simp]
theorem Differentiable.inv (hf : Differentiable π•œ h) (hz : βˆ€ x, h x β‰  0) :
Differentiable π•œ fun x => (h x)⁻¹ := fun x => (hf x).inv (hz x)
#align differentiable.inv Differentiable.inv

theorem derivWithin_inv' (hc : DifferentiableWithinAt π•œ c s x) (hx : c x β‰  0)
(hxs : UniqueDiffWithinAt π•œ s x) :
derivWithin (fun x => (c x)⁻¹) s x = -derivWithin c s x / c x ^ 2 :=
(hc.hasDerivWithinAt.inv hx).derivWithin hxs
#align deriv_within_inv' derivWithin_inv'

@[simp]
theorem deriv_inv'' (hc : DifferentiableAt π•œ c x) (hx : c x β‰  0) :
deriv (fun x => (c x)⁻¹) x = -deriv c x / c x ^ 2 :=
(hc.hasDerivAt.inv hx).deriv
#align deriv_inv'' deriv_inv''

end Inverse

section Division

/-! ### Derivative of `x ↦ c x / d x` -/

variable {π•œ' : Type _} [NontriviallyNormedField π•œ'] [NormedAlgebra π•œ π•œ'] {c d : π•œ β†’ π•œ'} {c' d' : π•œ'}

theorem HasDerivWithinAt.div (hc : HasDerivWithinAt c c' s x) (hd : HasDerivWithinAt d d' s x)
(hx : d x β‰  0) :
HasDerivWithinAt (fun y => c y / d y) ((c' * d x - c x * d') / d x ^ 2) s x := by
convert hc.mul ((hasDerivAt_inv hx).comp_hasDerivWithinAt x hd) using 1
· simp only [div_eq_mul_inv, (· ∘ ·)]
Β· field_simp
ring
#align has_deriv_within_at.div HasDerivWithinAt.div

theorem HasStrictDerivAt.div (hc : HasStrictDerivAt c c' x) (hd : HasStrictDerivAt d d' x)
(hx : d x β‰  0) : HasStrictDerivAt (fun y => c y / d y) ((c' * d x - c x * d') / d x ^ 2) x := by
convert hc.mul ((hasStrictDerivAt_inv hx).comp x hd) using 1
· simp only [div_eq_mul_inv, (· ∘ ·)]
Β· field_simp
ring
#align has_strict_deriv_at.div HasStrictDerivAt.div

theorem HasDerivAt.div (hc : HasDerivAt c c' x) (hd : HasDerivAt d d' x) (hx : d x β‰  0) :
HasDerivAt (fun y => c y / d y) ((c' * d x - c x * d') / d x ^ 2) x := by
rw [← hasDerivWithinAt_univ] at *
exact hc.div hd hx
#align has_deriv_at.div HasDerivAt.div

theorem DifferentiableWithinAt.div (hc : DifferentiableWithinAt π•œ c s x)
(hd : DifferentiableWithinAt π•œ d s x) (hx : d x β‰  0) :
DifferentiableWithinAt π•œ (fun x => c x / d x) s x :=
(hc.hasDerivWithinAt.div hd.hasDerivWithinAt hx).differentiableWithinAt
#align differentiable_within_at.div DifferentiableWithinAt.div

@[simp]
theorem DifferentiableAt.div (hc : DifferentiableAt π•œ c x) (hd : DifferentiableAt π•œ d x)
(hx : d x β‰  0) : DifferentiableAt π•œ (fun x => c x / d x) x :=
(hc.hasDerivAt.div hd.hasDerivAt hx).differentiableAt
#align differentiable_at.div DifferentiableAt.div

theorem DifferentiableOn.div (hc : DifferentiableOn π•œ c s) (hd : DifferentiableOn π•œ d s)
(hx : βˆ€ x ∈ s, d x β‰  0) : DifferentiableOn π•œ (fun x => c x / d x) s := fun x h =>
(hc x h).div (hd x h) (hx x h)
#align differentiable_on.div DifferentiableOn.div

@[simp]
theorem Differentiable.div (hc : Differentiable π•œ c) (hd : Differentiable π•œ d) (hx : βˆ€ x, d x β‰  0) :
Differentiable π•œ fun x => c x / d x := fun x => (hc x).div (hd x) (hx x)
#align differentiable.div Differentiable.div

theorem derivWithin_div (hc : DifferentiableWithinAt π•œ c s x) (hd : DifferentiableWithinAt π•œ d s x)
(hx : d x β‰  0) (hxs : UniqueDiffWithinAt π•œ s x) :
derivWithin (fun x => c x / d x) s x =
(derivWithin c s x * d x - c x * derivWithin d s x) / d x ^ 2 :=
(hc.hasDerivWithinAt.div hd.hasDerivWithinAt hx).derivWithin hxs
#align deriv_within_div derivWithin_div

@[simp]
theorem deriv_div (hc : DifferentiableAt π•œ c x) (hd : DifferentiableAt π•œ d x) (hx : d x β‰  0) :
deriv (fun x => c x / d x) x = (deriv c x * d x - c x * deriv d x) / d x ^ 2 :=
(hc.hasDerivAt.div hd.hasDerivAt hx).deriv
#align deriv_div deriv_div

end Division

0 comments on commit a206a3e

Please sign in to comment.