Skip to content

Commit 6441dda

Browse files
committed
derive row_mx
- with is_derive, is_diff instances
1 parent af08f5e commit 6441dda

4 files changed

Lines changed: 207 additions & 16 deletions

File tree

CHANGELOG_UNRELEASED.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@
9393
+ lemma `is_diff_mx`
9494
+ instance `is_diff_mx`
9595

96+
- in `derive.v`:
97+
+ lemmas `derivable_row_mx`, `derive_row_mx`
98+
+ instance `is_derive_row_mx`
99+
100+
- in `matrix_normedtype.v`
101+
+ lemmas `norm_row_mx`, `norm_row_mx0r`, `norm_row_mx0l`
102+
103+
- in `unstable.v`:
104+
+ lemma `sub_row_mx`
105+
106+
- in `derive.v`:
107+
+ lemmas `eqo_row_mx`, `cvg_row_mx`, `drow_mx`, `diff_row_mx`,
108+
`differentiable_row_mx`
109+
+ instance `is_diff_row_mx`
110+
96111
### Changed
97112

98113
- moved from `measurable_structure.v` to `classical_sets.v`:

classical/unstable.v

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(* mathcomp analysis (c) 2026 Inria and AIST. License: CeCILL-C. *)
22
From HB Require Import structures.
33
From mathcomp Require Import all_ssreflect_compat finmap ssralg ssrnum ssrint.
4-
From mathcomp Require Import vector archimedean interval.
4+
From mathcomp Require Import vector archimedean interval matrix.
55

66
(**md**************************************************************************)
77
(* # MathComp extra *)
@@ -47,6 +47,11 @@ Unset Printing Implicit Defensive.
4747
Import Order.TTheory GRing.Theory Num.Theory.
4848
Local Open Scope ring_scope.
4949

50+
Lemma sub_row_mx {V : zmodType} m n1 n2 (A1 : 'M[V]_(m, n1)) (A2 : 'M[V]_(m, n2))
51+
(B1 : 'M[V]_(m, n1)) (B2 : 'M[V]_(m, n2)) :
52+
row_mx A1 A2 - row_mx B1 B2 = row_mx (A1 - B1) (A2 - B2).
53+
Proof. by rewrite opp_row_mx add_row_mx. Qed.
54+
5055
Section IntervalNumDomain.
5156
Variable R : numDomainType.
5257
Implicit Types x : R.

theories/derive.v

Lines changed: 133 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ Lemma deriveEjacobian m n (f : 'rV[R]_m -> 'rV[R]_n) (a v : 'rV[R]_m) :
377377
Proof. by move=> /deriveE->; rewrite /jacobian mul_rV_lin1. Qed.
378378

379379
Definition derive1 V (f : R -> V) (a : R) :=
380-
lim ((fun h => h^-1 *: (f (h + a) - f a)) @ 0^').
380+
lim ((fun h => h^-1 *: (f (h + a) - f a)) @ 0^').
381381

382382
Local Notation "f ^` ()" := (derive1 f).
383383

@@ -2330,7 +2330,7 @@ Unshelve. all: by end_near. Qed.
23302330

23312331
Global Instance is_derive_mx {m n : nat} (M : V -> 'M[R]_(m, n))
23322332
(dM : 'M[R]_(m, n)) (x v : V) :
2333-
(forall i j, is_derive x v (fun x => M x i j) (dM i j)) ->
2333+
(forall i j, is_derive x v (fun t => M t i j) (dM i j)) ->
23342334
is_derive x v M dM.
23352335
Proof.
23362336
move=> MdM; apply: DeriveDef; first exact/derivable_mxP.
@@ -2342,7 +2342,7 @@ by have [] := MdM i0 j0.
23422342
Qed.
23432343

23442344
Fact dmx {m n : nat} (M : V -> 'M[R]_(m, n)) (x : V) :
2345-
let g := fun x0 : V => (\matrix_(i < m, j < n) 'd M x x0 i j) in
2345+
let g := fun t : V => (\matrix_(i < m, j < n) 'd M x t i j) in
23462346
differentiable M x ->
23472347
continuous g /\
23482348
M \o shift x = cst (M x) + g +o_ 0 id.
@@ -2357,13 +2357,13 @@ move=> dM Mx; split => [|].
23572357
by apply/matrixP => i j/=; rewrite mxE.
23582358
Qed.
23592359

2360-
Lemma diffmx {m n : nat} (M : V -> 'M[R]_(m, n)) t :
2361-
differentiable M t ->
2362-
'd M (nbhs_filter_on t) =
2363-
(fun x0 : V => \matrix_(i < m, j < n) 'd M t x0 i j) :> (_ -> _).
2360+
Lemma diffmx {m n : nat} (M : V -> 'M[R]_(m, n)) x :
2361+
differentiable M x ->
2362+
'd M (nbhs_filter_on x) =
2363+
(fun t : V => \matrix_(i < m, j < n) 'd M x t i j) :> (_ -> _).
23642364
Proof.
23652365
move=> dM.
2366-
set g := fun x0 : V => \matrix_(i, j) 'd M t x0 i j.
2366+
set g := fun t : V => \matrix_(i, j) 'd M x t i j.
23672367
have glin : linear (g : V -> _).
23682368
move=> a u w.
23692369
by rewrite /g linearD linearZ/=; apply/matrixP => i j; rewrite !mxE.
@@ -2379,16 +2379,14 @@ Local Open Scope classical_set_scope.
23792379
Context {R : realFieldType}.
23802380

23812381
Global Instance is_diff_mx {m n : nat} (M dM : R -> 'M[R]_(m, n)) (x : R) :
2382-
(forall i j, is_diff x (fun x => M x i j) (fun x => dM x i j)) ->
2382+
(forall i j, is_diff x (fun t => M t i j) (fun t => dM t i j)) ->
23832383
is_diff x M dM.
23842384
Proof.
23852385
move=> /= MdM.
2386-
have diffM : differentiable M (nbhs_filter_on x).
2386+
have diffMx : differentiable M (nbhs_filter_on x).
23872387
apply/derivable1_diffP; apply/derivable_mxP => i j.
2388-
by have [/(@derivable1_diffP _ _ (fun x0 => M x0 i j) x)] := MdM i j.
2389-
have diffMx i j : differentiable (fun x0 : R => M x0 i j) x.
2390-
by have [/=] := MdM i j.
2391-
apply: DiffDef; first exact: diffM.
2388+
by have [/(@derivable1_diffP _ _ (fun t => M t i j) x)] := MdM i j.
2389+
apply: DiffDef; first exact: diffMx.
23922390
rewrite diffmx//=; apply/funext => /= v; apply/matrixP => i j.
23932391
rewrite !mxE.
23942392
have [diffMij dMdM] := MdM i j.
@@ -2401,3 +2399,124 @@ by have [/diff_derivable-/(_ v)] := MdM i0 j0.
24012399
Qed.
24022400

24032401
End Ris_diff_mx.
2402+
2403+
Section derivable_derive_row_mx.
2404+
Context {R : realFieldType} {V : normedModType R} {n1 n2 : nat}.
2405+
Implicit Types (f : V -> 'rV[R]_n1) (g : V -> 'rV[R]_n2).
2406+
2407+
Lemma derivable_row_mx f g t v : derivable f t v -> derivable g t v ->
2408+
derivable (fun x => row_mx (f x) (g x)) t v.
2409+
Proof.
2410+
move=> /= fv gv; apply/derivable_mxP => i j; rewrite (ord1 i)/=.
2411+
have /cvg_ex[/= l Hl] := fv.
2412+
have /cvg_ex[/= k Hk] := gv.
2413+
apply/cvg_ex => /=; exists (row_mx l k ord0 j).
2414+
apply/cvgrPdist_le => /= e e0.
2415+
move/cvgrPdist_le : Hl => /(_ _ e0) Hl.
2416+
move/cvgrPdist_le : Hk => /(_ _ e0) Hk.
2417+
move: Hl Hk; apply: filterS2 => x Hl Hk.
2418+
rewrite !mxE; case: fintype.splitP => j1 jj1.
2419+
- rewrite (le_trans _ Hl)// [in leRHS]/Num.Def.normr/= mx_normrE.
2420+
by rewrite (le_trans _ (le_bigmax _ _ (ord0, j1)))// !mxE.
2421+
- rewrite (le_trans _ Hk)// [in leRHS]/Num.Def.normr/= mx_normrE.
2422+
by rewrite (le_trans _ (le_bigmax _ _ (ord0, j1)))// !mxE.
2423+
Qed.
2424+
2425+
Lemma derive_row_mx f g t v : derivable f t v -> derivable g t v ->
2426+
'D_v (fun x => row_mx (f x) (g x)) t = row_mx ('D_v f t) ('D_v g t).
2427+
Proof.
2428+
move=> fv gv; rewrite derive_mx.
2429+
by apply: derivable_row_mx; [exact: fv|exact: gv].
2430+
apply/matrixP => i j.
2431+
rewrite !mxE !derive_mx//; case: splitP => k jE; rewrite !mxE; congr ('D_v _ t);
2432+
apply/funext => w; rewrite !mxE; case: splitP => l lE//.
2433+
- by congr (f w i _); apply/val_inj => /=; rewrite -jE -lE.
2434+
- by absurd: lE; rewrite ltn_eqF//= jE (leq_trans (ltn_ord k))// leq_addr.
2435+
- by absurd: lE; rewrite gtn_eqF//= jE (leq_trans (ltn_ord l))// leq_addr.
2436+
- congr (g w i _); apply/val_inj => /=.
2437+
by apply/eqP; rewrite -(eqn_add2l n1) -lE -jE.
2438+
Qed.
2439+
2440+
Global Instance is_derive_row_mx f A g B x v :
2441+
is_derive x v f A -> is_derive x v g B ->
2442+
is_derive x v (fun t => row_mx (f t) (g t)) (row_mx A B).
2443+
Proof.
2444+
move=> [dfx fA] [dgx gB]; apply: DeriveDef; first exact: derivable_row_mx.
2445+
by rewrite derive_row_mx// fA gB.
2446+
Qed.
2447+
2448+
End derivable_derive_row_mx.
2449+
2450+
Lemma eqo_row_mx (K : realFieldType) {m n1 n2 : nat} (F : filter_on K)
2451+
(A1 : K -> 'M[K]_(m, n1)) (A2 : K -> 'M[K]_(m, n2)) :
2452+
(fun t => row_mx ([o_F id of A1] t) ([o_F id of A2] t)) =o_F id.
2453+
Proof.
2454+
apply/eqoP => _/posnumP[e]; near=> x; rewrite norm_row_mx ge_max.
2455+
by apply/andP; split; near: x; apply: littleoP.
2456+
Unshelve. all: by end_near. Qed.
2457+
2458+
(* NB: this could be moved earlier in the file hierarchy *)
2459+
Lemma cvg_row_mx {T : realFieldType} {F : set_system T} {n1 n2 : nat}
2460+
(G : 'rV[T]_n1) (H : 'rV[T]_n2) : Filter F ->
2461+
forall (f : T -> 'rV[T]_n1) (g : T -> 'rV[T]_n2),
2462+
f x @[x --> F] --> G -> g x @[x --> F] --> H ->
2463+
row_mx (f x) (g x) @[x --> F] --> row_mx G H.
2464+
Proof.
2465+
move=> FF M N cvgM cvgN; apply/cvgrPdist_le => /= e e0; near=> t.
2466+
rewrite sub_row_mx norm_row_mx ge_max; apply/andP; split.
2467+
- by near: t; move/cvgrPdist_le : cvgM => /(_ _ e0).
2468+
- by near: t; move/cvgrPdist_le : cvgN => /(_ _ e0).
2469+
Unshelve. all: by end_near. Qed.
2470+
2471+
Section is_diff_row_mx.
2472+
Local Open Scope classical_set_scope.
2473+
Context {R : realFieldType} {n1 n2 : nat}.
2474+
Implicit Types (M dM : R -> 'rV[R]_n1) (N dN : R -> 'rV[R]_n2) (x t : R).
2475+
2476+
Fact drow_mx M N x : differentiable M x -> differentiable N x ->
2477+
continuous (fun y => row_mx ('d M x y) ('d N x y)) /\
2478+
(fun y => row_mx (M y) (N y)) \o shift x = cst (row_mx (M x) (N x)) +
2479+
(fun y => row_mx ('d M x y) ('d N x y)) +o_ 0 id.
2480+
Proof.
2481+
move=> df dg; split=> [/= ?|].
2482+
by apply: cvg_row_mx => //=; exact: diff_continuous.
2483+
apply/eqaddoE; rewrite funeqE => y /=.
2484+
rewrite ![_ (_ + x)]diff_locallyx//.
2485+
have ->/= : forall h e, row_mx (M x + 'd M x y + [o_ 0 id of h] y)
2486+
(N x + 'd N x y + [o_ 0 id of e] y) =
2487+
row_mx (M x) (N x) + row_mx ('d M x y) ('d N x y) +
2488+
row_mx ([o_ 0 id of h] y) ([o_ 0 id of e] y).
2489+
by move=> /= h e; rewrite !add_row_mx.
2490+
congr (_ + _).
2491+
by rewrite -[LHS]/((fun y => row_mx (_ y) (_ y)) y) eqo_row_mx.
2492+
Qed.
2493+
2494+
Lemma diff_row_mx M N x : differentiable M x -> differentiable N x ->
2495+
'd (fun y => row_mx (M y) (N y)) x =
2496+
(fun y => row_mx ('d M x y) ('d N x y)) :> (R -> 'rV[R]_(n1 + n2)).
2497+
Proof.
2498+
move=> df dg.
2499+
pose d y := row_mx ('d M x y) ('d N x y).
2500+
have lin_row_mx : linear d.
2501+
by move=> /= a b c; rewrite /d 2!linearPZ scale_row_mx add_row_mx.
2502+
pose row_mxlM := GRing.isLinear.Build _ _ _ _ _ lin_row_mx.
2503+
pose row_mxL : {linear _ -> _} := HB.pack d row_mxlM.
2504+
rewrite -/d -[d]/(row_mxL : _ -> _).
2505+
by apply: diff_unique; have [] := drow_mx df dg.
2506+
Qed.
2507+
2508+
Lemma differentiable_row_mx M N x : differentiable M x -> differentiable N x ->
2509+
differentiable (fun t => row_mx (M t) (N t)) x.
2510+
Proof.
2511+
by move=> df dg; apply/diff_locallyP; rewrite diff_row_mx //; apply: drow_mx.
2512+
Qed.
2513+
2514+
Global Instance is_diff_row_mx M dM N dN x :
2515+
is_diff x M dM -> is_diff x N dN ->
2516+
is_diff x (fun t => row_mx (M t) (N t)) (fun t => row_mx (dM t) (dN t)).
2517+
Proof.
2518+
move=> dfx dgx; apply: DiffDef; first exact: differentiable_row_mx.
2519+
by rewrite diff_row_mx// !diff_val.
2520+
Qed.
2521+
2522+
End is_diff_row_mx.

theories/normedtype_theory/matrix_normedtype.v

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
From HB Require Import structures.
33
From mathcomp Require Import all_ssreflect_compat finmap ssralg ssrnum matrix.
44
From mathcomp Require Import interval interval_inference.
5-
From mathcomp Require Import boolp classical_sets reals topology.
5+
From mathcomp Require Import boolp contra classical_sets reals topology.
66
From mathcomp Require Import prodnormedzmodule tvs pseudometric_normed_Zmodule.
77
From mathcomp Require Import normed_module.
88

@@ -274,3 +274,55 @@ split => [cf x|cf i j v].
274274
apply: le_trans (le_bigmax _ _ (i, j)).
275275
by rewrite !mxE.
276276
Unshelve. all: by end_near. Qed.
277+
278+
Section norm_row_mx.
279+
Context {K : realDomainType} {m n1 n2 : nat}.
280+
Implicit Types (M : 'M[K]_(m, n1)) (N : 'M[K]_(m, n2)).
281+
282+
Lemma norm_row_mx0r M : `|row_mx M (0 : 'M_(m, n2))| = `|M|.
283+
Proof.
284+
apply/eqP; rewrite eq_le; apply/andP; split.
285+
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
286+
rewrite mxE; case: splitP => k kE; last by rewrite mxE normr0.
287+
by rewrite [leRHS]/Num.norm/= !mx_normrE/= (le_bigmax _ _ (i, k)).
288+
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
289+
rewrite [leRHS]/Num.norm/= !mx_normrE/=.
290+
rewrite (le_trans _(le_bigmax _ _ (i, lshift n2 j)))// mxE/=.
291+
case: splitP => // k kE.
292+
rewrite (_ : j = k)//; apply: val_inj => /=.
293+
by apply/eqP; rewrite -(eqn_add2l n1) -kE.
294+
absurd: kE.
295+
by rewrite ltn_eqF// (leq_trans (ltn_ord j))// /lshift/= leq_addr.
296+
Qed.
297+
298+
Lemma norm_row_mx0l N : `|row_mx (0 : 'M_(m, n1)) N| = `|N|.
299+
Proof.
300+
apply/eqP; rewrite eq_le; apply/andP; split.
301+
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
302+
rewrite mxE; case: splitP => k kE; first by rewrite mxE normr0.
303+
by rewrite [leRHS]/Num.norm/= !mx_normrE/= (le_bigmax _ _ (i, k)).
304+
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
305+
rewrite [leRHS]/Num.norm/= !mx_normrE/=.
306+
rewrite (le_trans _ (le_bigmax _ _ (i, rshift n1 j)))// mxE/=.
307+
case: splitP => // k kE.
308+
absurd: kE.
309+
by rewrite gtn_eqF// (leq_trans (ltn_ord k))// /rshift/= leq_addr.
310+
rewrite (_ : j = k)//; apply: val_inj => /=.
311+
by apply/eqP; rewrite -(eqn_add2l n1) -kE.
312+
Qed.
313+
314+
Lemma norm_row_mx M N : `|row_mx M N| = Num.max `|M| `|N|.
315+
Proof.
316+
apply/eqP; rewrite eq_le; apply/andP; split.
317+
- rewrite [leLHS]/Num.norm/= !mx_normrE bigmax_le//= => -[i j] _/=.
318+
rewrite le_max mxE; case: splitP => k kE.
319+
+ by rewrite [in `|M|]/Num.norm/= !mx_normrE (le_bigmax _ _ (i, k)).
320+
+ by rewrite [in `|N|]/Num.norm/= !mx_normrE (le_bigmax _ _ (i, k)) ?orbT.
321+
- rewrite ge_max; apply/andP; split;
322+
rewrite [leLHS]/Num.norm/= !mx_normrE bigmax_le//= => -[i j] _/=;
323+
rewrite [leRHS]/Num.norm/= !mx_normrE.
324+
+ by rewrite -(row_mxEl _ N)/= (le_bigmax _ _ (i, lshift n2 j)).
325+
+ by rewrite -(row_mxEr M)/= (le_bigmax _ _ (i, rshift n1 j)).
326+
Qed.
327+
328+
End norm_row_mx.

0 commit comments

Comments
 (0)