11. 微分

ここから 解析学 の概念の形式化について考えていきましょう.この章では微分から始め,次の章では積分と測度論を取り上げます. Section 11.1 では,微積分の入門クラスでおなじみの実数から実数への関数設定に限定します. Section 11.2 では導関数の概念をより広い範囲で考えます.

11.1. 初等的な微分法

f を実数から実数への関数としたとき,ある1点における f の微分係数について話すのと導関数について話すのとでは違いがあります.Mathlibでは,前者の概念は次のように表現されます.

open Real

/-- The sin function has derivative 1 at 0. -/
example : HasDerivAt sin 1 0 := by simpa using hasDerivAt_sin 0

また,特定の点での微分を指定せずに f が微分可能であることも表現でき, DifferentiableAt と書きます.ここで, を明示的に指定しているのは,もう少し一般的な文脈において から までの関数について話す時に,実数的な意味で微分可能であることと,複素微分の意味で微分可能であることを区別できるようにしたいからです.

example (x : ) : DifferentiableAt  sin x :=
  (hasDerivAt_sin x).differentiableAt

微分について言及するたびに微分可能性の証明をしなければならないのは不便です.そこで,Mathlibは関数 deriv f : を提供しています.これは任意の関数 f : に対して定義されますが, f が微分不可能な点では 0 をとるように定義されています.

example {f :   } {x a : } (h : HasDerivAt f a x) : deriv f x = a :=
  h.deriv

example {f :   } {x : } (h : ¬DifferentiableAt  f x) : deriv f x = 0 :=
  deriv_zero_of_not_differentiableAt h

もちろん deriv に関する補題で微分可能性の仮定を必要とするものはたくさんあります.例えば,微分可能性の仮定がない場合の次の補題の反例を考えてみるといいでしょう.

example {f g :   } {x : } (hf : DifferentiableAt  f x) (hg : DifferentiableAt  g x) :
    deriv (f + g) x = deriv f x + deriv g x :=
  deriv_add hf hg

しかし興味深いことに,関数が微分可能でない場合, deriv の値がデフォルトで0になるという事実を利用することで,微分可能性の仮定を回避できる文が存在します.そのため,以下の文の意味を理解するには deriv の正確な定義を知る必要があります.

example {f :   } {a : } (h : IsLocalMin f a) : deriv f a = 0 :=
  h.deriv_eq_zero

より奇妙に見えるでしょうが,微分可能性の仮定なしにロルの定理を示すことさえできます.

open Set

example {f :   } {a b : } (hab : a < b) (hfc : ContinuousOn f (Icc a b)) (hfI : f a = f b) :
     c  Ioo a b, deriv f c = 0 :=
  exists_deriv_eq_zero hab hfc hfI

もちろん,この技法は一般的な平均値の定理には通用しません.

example (f :   ) {a b : } (hab : a < b) (hf : ContinuousOn f (Icc a b))
    (hf' : DifferentiableOn  f (Ioo a b)) :  c  Ioo a b, deriv f c = (f b - f a) / (b - a) :=
  exists_deriv_eq_slope f hab hf hf'

Leanは simp タクティクを使って簡単な微分係数を自動的に計算することができます.

example : deriv (fun x :   x ^ 5) 6 = 5 * 6 ^ 4 := by simp

example : deriv sin π = -1 := by simp

11.2. ノルム空間の微分法

11.2.1. ノルム空間

微分は,方向と距離の両方を備えた ノルム線形空間 (normed vector space)の概念を用いることで を超えて一般化することができます.まず ノルム化された群 (normed group)の概念から始めましょう.これは以下の条件を満たす実数値ノルム関数を備えた加法可換群です.

variable {E : Type*} [NormedAddCommGroup E]

example (x : E) : 0  x :=
  norm_nonneg x

example {x : E} : x = 0  x = 0 :=
  norm_eq_zero

example (x y : E) : x + y  x + y :=
  norm_add_le x y

すべてのノルム空間は距離関数 \(d(x, y) = \| x - y \|\) を持つ距離空間であり,したがって位相空間でもあります.LeanとMathlibはこの事実を知っています.

example : MetricSpace E := by infer_instance

example {X : Type*} [TopologicalSpace X] {f : X  E} (hf : Continuous f) :
    Continuous fun x  f x :=
  hf.norm

線形代数からのコンセプトとノルムの概念を使うために, NormedAddGroup E の上に NormedSpace E という仮定を追加します.これは E 上のベクトル空間であり,スカラー倍が以下の条件を満たすことを定めます.

variable [NormedSpace  E]

example (a : ) (x : E) : a  x = |a| * x :=
  norm_smul a x

完備なノルム空間は バナッハ空間 (Banach space)として知られています.すべての有限次元ベクトル空間は完備です.

example [FiniteDimensional  E] : CompleteSpace E := by infer_instance

これまでの例はすべてベースの体として実数を使いました.より一般的には,任意の 非自明なノルム化された体 (nontrivially normed field)上のベクトル空間を使って微積分を理解することができます.これは乗法的ですべての要素のノルムが0か1ではない(つまり,ノルムが1より大きい要素が存在する)という性質を持つ実数値ノルムを備えた体です.

example (𝕜 : Type*) [NontriviallyNormedField 𝕜] (x y : 𝕜) : x * y = x * y :=
  norm_mul x y

example (𝕜 : Type*) [NontriviallyNormedField 𝕜] :  x : 𝕜, 1 < x :=
  NormedField.exists_one_lt_norm 𝕜

非自明なノルム化された体上の有限次元ベクトル空間はその体自体が完備である場合に限り完備です.

example (𝕜 : Type*) [NontriviallyNormedField 𝕜] (E : Type*) [NormedAddCommGroup E]
    [NormedSpace 𝕜 E] [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] : CompleteSpace E :=
  FiniteDimensional.complete 𝕜 E

11.2.2. 連続線形写像

次にノルム空間の圏における射,つまり連続線形写像について説明します.Mathlibでは,ノルム空間 EF の間の 𝕜 線形連続写像の型を E →L[𝕜] F と表記します.これらは 束縛写像 (bundled maps)として実装されます.束縛写像とは,この型の要素が関数そのものと線形で連続であるという性質を含む構造を持つことを意味します.Leanは連続線形写像を関数として扱えるように型強制を備えています.

variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E]
  [NormedSpace 𝕜 E] {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F]

example : E L[𝕜] E :=
  ContinuousLinearMap.id 𝕜 E

example (f : E L[𝕜] F) : E  F :=
  f

example (f : E L[𝕜] F) : Continuous f :=
  f.cont

example (f : E L[𝕜] F) (x y : E) : f (x + y) = f x + f y :=
  f.map_add x y

example (f : E L[𝕜] F) (a : 𝕜) (x : E) : f (a  x) = a  f x :=
  f.map_smul a x

連続線形写像は以下の性質で特徴づけられる作用素ノルムを持ちます.

variable (f : E L[𝕜] F)

example (x : E) : f x  f * x :=
  f.le_opNorm x

example {M : } (hMp : 0  M) (hM :  x, f x  M * x) : f  M :=
  f.opNorm_le_bound hMp hM

また束縛された連続線形 同型 (isomorphism)という概念が存在します.この型は E ≃L[𝕜] F です.

発展的な演習として,一様有界性原理としても知られているバナッハ-シュタインハウスの定理を証明してみましょう.この原理はバナッハ空間からノルム空間への連続線形写像の族が点ごとに有界であれば,これらの線形写像のノルムは一様に有界であることを述べています.この証明の主成分はベールの定理 nonempty_interior_of_iUnion_of_closed です.(位相の章でこれを証明しました.)それ以外の材料として continuous_linear_map.opNorm_le_of_shellinterior_subsetinterior_iInter_subsetisClosed_le が含まれます.

variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E]
  [NormedSpace 𝕜 E] {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F]

open Metric

example {ι : Type*} [CompleteSpace E] {g : ι  E L[𝕜] F} (h :  x,  C,  i, g i x  C) :
     C',  i, g i  C' := by
  -- sequence of subsets consisting of those `x : E` with norms `‖g i x‖` bounded by `n`
  let e :   Set E := fun n   i : ι, { x : E | g i x  n }
  -- each of these sets is closed
  have hc :  n : , IsClosed (e n)
  sorry
  -- the union is the entire space; this is where we use `h`
  have hU : ( n : , e n) = univ
  sorry
  /- apply the Baire category theorem to conclude that for some `m : ℕ`,
       `e m` contains some `x` -/
  obtain m, x, hx :  m,  x, x  interior (e m) := sorry
  obtain ε, ε_pos,  :  ε > 0, ball x ε  interior (e m) := sorry
  obtain k, hk :  k : 𝕜, 1 < k := sorry
  -- show all elements in the ball have norm bounded by `m` after applying any `g i`
  have real_norm_le :  z  ball x ε,  (i : ι), g i z  m
  sorry
  have εk_pos : 0 < ε / k := sorry
  refine ⟨(m + m : ) / (ε / k), fun i  ContinuousLinearMap.opNorm_le_of_shell ε_pos ?_ hk ?_
  sorry
  sorry

11.2.3. 漸近比較

微分可能性の定義には漸近比較も必要です.Mathlibにはビッグオーとリトルオーの関係をカバーする広範なライブラリがあり,その定義を以下に示されるものです. asymptotics 名前空間を開くと,対応する表記法を使うことができます.ここでは微分可能性を定義するためにリトルオーのみを使用します.

open Asymptotics

example {α : Type*} {E : Type*} [NormedGroup E] {F : Type*} [NormedGroup F] (c : )
    (l : Filter α) (f : α  E) (g : α  F) : IsBigOWith c l f g  ∀ᶠ x in l, f x  c * g x :=
  isBigOWith_iff

example {α : Type*} {E : Type*} [NormedGroup E] {F : Type*} [NormedGroup F]
    (l : Filter α) (f : α  E) (g : α  F) : f =O[l] g   C, IsBigOWith C l f g :=
  isBigO_iff_isBigOWith

example {α : Type*} {E : Type*} [NormedGroup E] {F : Type*} [NormedGroup F]
    (l : Filter α) (f : α  E) (g : α  F) : f =o[l] g   C > 0, IsBigOWith C l f g :=
  isLittleO_iff_forall_isBigOWith

example {α : Type*} {E : Type*} [NormedAddCommGroup E] (l : Filter α) (f g : α  E) :
    f ~[l] g  (f - g) =o[l] g :=
  Iff.rfl

11.2.4. 微分可能性

これでノルム空間のあいだの微分可能な関数について議論する準備が整いました.初等的な一次元の場合になぞらえて,Mathlibでは HasFDerivAt という述語と fderiv という関数と定義しています.ここで fフレシェ (Fréchet)を表します.

open Topology

variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E]
  [NormedSpace 𝕜 E] {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F]

example (f : E  F) (f' : E L[𝕜] F) (x₀ : E) :
    HasFDerivAt f f' x₀  (fun x  f x - f x₀ - f' (x - x₀)) =o[𝓝 x₀] fun x  x - x₀ :=
  hasFDerivAtFilter_iff_isLittleO ..

example (f : E  F) (f' : E L[𝕜] F) (x₀ : E) (hff' : HasFDerivAt f f' x₀) : fderiv 𝕜 f x₀ = f' :=
  hff'.fderiv

またMathlibには,多重線形写像 E [×n]→L[𝕜] F 型で値をとる反復微分や,連続微分関数も存在します.型 WithTop にすべての自然数より大きい要素 を加えたものです.つまり関数 \(\mathcal{C}^\infty\)ContDiff 𝕜 f を満たす関数 f です.

example (n : ) (f : E  F) : E  E[×n]L[𝕜] F :=
  iteratedFDeriv 𝕜 n f

example (n : WithTop ) {f : E  F} :
    ContDiff 𝕜 n f 
      ( m : , (m : WithTop )  n  Continuous fun x  iteratedFDeriv 𝕜 m f x) 
         m : , (m : WithTop ) < n  Differentiable 𝕜 fun x  iteratedFDeriv 𝕜 m f x :=
  contDiff_iff_continuous_differentiable

より狭義な微分可能性の概念で HasStrictFDerivAt と呼ばれるものがあります.これはMathlibにある逆関数定理と陰関数定理の記述で使われています. もしくは 上の連続微分可能な関数は狭義微分可能です.

example {𝕂 : Type*} [RCLike 𝕂] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕂 E] {F : Type*}
    [NormedAddCommGroup F] [NormedSpace 𝕂 F] {f : E  F} {x : E} {n : WithTop }
    (hf : ContDiffAt 𝕂 n f x) (hn : 1  n) : HasStrictFDerivAt f (fderiv 𝕂 f x) x :=
  hf.hasStrictFDerivAt hn

局所的な逆関数定理は,ある関数から逆関数を生成する操作と,その関数がある点 a において狭義微分可能であり,その導関数と同型であるという仮定を用いて述べられます.

以下の最初の例は,この局所的な逆関数を求めるためのものです.その次の例はこれが左右どちらからも局所的な逆であることを確かめ,そして狭義微分可能であることを述べています.

section LocalInverse
variable [CompleteSpace E] {f : E  F} {f' : E L[𝕜] F} {a : E}

example (hf : HasStrictFDerivAt f (f' : E L[𝕜] F) a) : F  E :=
  HasStrictFDerivAt.localInverse f f' a hf

example (hf : HasStrictFDerivAt f (f' : E L[𝕜] F) a) :
    ∀ᶠ x in 𝓝 a, hf.localInverse f f' a (f x) = x :=
  hf.eventually_left_inverse

example (hf : HasStrictFDerivAt f (f' : E L[𝕜] F) a) :
    ∀ᶠ x in 𝓝 (f a), f (hf.localInverse f f' a x) = x :=
  hf.eventually_right_inverse

example {f : E  F} {f' : E L[𝕜] F} {a : E}
  (hf : HasStrictFDerivAt f (f' : E L[𝕜] F) a) :
    HasStrictFDerivAt (HasStrictFDerivAt.localInverse f f' a hf) (f'.symm : F L[𝕜] E) (f a) :=
  HasStrictFDerivAt.to_localInverse hf

end LocalInverse

以上,Mathlibの微分をざっと見てきました.Mathlibにはこれまでに説明しなかった多くの情報が含まれています.例えば,1次元の設定での片側微分を使いたいとしましょう.これについてMathlibにはより一般的な文脈のものがあります; HasFDerivWithinAt や,さらに一般的な HasFDerivAtFilter を参照してください.