Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG_UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@
+ lemma `is_diff_mx`
+ instance `is_diff_mx`

- in `derive.v`:
+ lemmas `derivable_row_mx`, `derive_row_mx`
+ instance `is_derive_row_mx`

- in `matrix_normedtype.v`
+ lemmas `norm_row_mx`, `norm_row_mx0r`, `norm_row_mx0l`

- in `unstable.v`:
+ lemma `sub_row_mx`

- in `derive.v`:
+ lemmas `eqo_row_mx`, `cvg_row_mx`, `drow_mx`, `diff_row_mx`,
`differentiable_row_mx`
+ instance `is_diff_row_mx`

### Changed

- moved from `measurable_structure.v` to `classical_sets.v`:
Expand Down
7 changes: 6 additions & 1 deletion classical/unstable.v
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(* mathcomp analysis (c) 2026 Inria and AIST. License: CeCILL-C. *)
From HB Require Import structures.
From mathcomp Require Import all_ssreflect_compat finmap ssralg ssrnum ssrint.
From mathcomp Require Import vector archimedean interval.
From mathcomp Require Import vector archimedean interval matrix.

(**md**************************************************************************)
(* # MathComp extra *)
Expand Down Expand Up @@ -47,6 +47,11 @@ Unset Printing Implicit Defensive.
Import Order.TTheory GRing.Theory Num.Theory.
Local Open Scope ring_scope.

Lemma sub_row_mx {V : zmodType} m n1 n2 (A1 : 'M[V]_(m, n1)) (A2 : 'M[V]_(m, n2))
(B1 : 'M[V]_(m, n1)) (B2 : 'M[V]_(m, n2)) :
row_mx A1 A2 - row_mx B1 B2 = row_mx (A1 - B1) (A2 - B2).
Proof. by rewrite opp_row_mx add_row_mx. Qed.

Section IntervalNumDomain.
Variable R : numDomainType.
Implicit Types x : R.
Expand Down
147 changes: 133 additions & 14 deletions theories/derive.v
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ Lemma deriveEjacobian m n (f : 'rV[R]_m -> 'rV[R]_n) (a v : 'rV[R]_m) :
Proof. by move=> /deriveE->; rewrite /jacobian mul_rV_lin1. Qed.

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

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

Expand Down Expand Up @@ -2330,7 +2330,7 @@ Unshelve. all: by end_near. Qed.

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

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

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

Global Instance is_diff_mx {m n : nat} (M dM : R -> 'M[R]_(m, n)) (x : R) :
(forall i j, is_diff x (fun x => M x i j) (fun x => dM x i j)) ->
(forall i j, is_diff x (fun t => M t i j) (fun t => dM t i j)) ->
is_diff x M dM.
Proof.
move=> /= MdM.
have diffM : differentiable M (nbhs_filter_on x).
have diffMx : differentiable M (nbhs_filter_on x).
apply/derivable1_diffP; apply/derivable_mxP => i j.
by have [/(@derivable1_diffP _ _ (fun x0 => M x0 i j) x)] := MdM i j.
have diffMx i j : differentiable (fun x0 : R => M x0 i j) x.
by have [/=] := MdM i j.
apply: DiffDef; first exact: diffM.
by have [/(@derivable1_diffP _ _ (fun t => M t i j) x)] := MdM i j.
apply: DiffDef; first exact: diffMx.
rewrite diffmx//=; apply/funext => /= v; apply/matrixP => i j.
rewrite !mxE.
have [diffMij dMdM] := MdM i j.
Expand All @@ -2401,3 +2399,124 @@ by have [/diff_derivable-/(_ v)] := MdM i0 j0.
Qed.

End Ris_diff_mx.

Section derivable_derive_row_mx.
Context {R : realFieldType} {V : normedModType R} {n1 n2 : nat}.
Implicit Types (f : V -> 'rV[R]_n1) (g : V -> 'rV[R]_n2).

Lemma derivable_row_mx f g t v : derivable f t v -> derivable g t v ->
derivable (fun x => row_mx (f x) (g x)) t v.
Proof.
move=> /= fv gv; apply/derivable_mxP => i j; rewrite (ord1 i)/=.
have /cvg_ex[/= l Hl] := fv.
have /cvg_ex[/= k Hk] := gv.
apply/cvg_ex => /=; exists (row_mx l k ord0 j).
apply/cvgrPdist_le => /= e e0.
move/cvgrPdist_le : Hl => /(_ _ e0) Hl.
move/cvgrPdist_le : Hk => /(_ _ e0) Hk.
move: Hl Hk; apply: filterS2 => x Hl Hk.
rewrite !mxE; case: fintype.splitP => j1 jj1.
- rewrite (le_trans _ Hl)// [in leRHS]/Num.Def.normr/= mx_normrE.
by rewrite (le_trans _ (le_bigmax _ _ (ord0, j1)))// !mxE.
- rewrite (le_trans _ Hk)// [in leRHS]/Num.Def.normr/= mx_normrE.
by rewrite (le_trans _ (le_bigmax _ _ (ord0, j1)))// !mxE.
Qed.

Lemma derive_row_mx f g t v : derivable f t v -> derivable g t v ->
'D_v (fun x => row_mx (f x) (g x)) t = row_mx ('D_v f t) ('D_v g t).
Proof.
move=> fv gv; rewrite derive_mx.
by apply: derivable_row_mx; [exact: fv|exact: gv].
apply/matrixP => i j.
rewrite !mxE !derive_mx//; case: splitP => k jE; rewrite !mxE; congr ('D_v _ t);
apply/funext => w; rewrite !mxE; case: splitP => l lE//.
- by congr (f w i _); apply/val_inj => /=; rewrite -jE -lE.
- by absurd: lE; rewrite ltn_eqF//= jE (leq_trans (ltn_ord k))// leq_addr.
- by absurd: lE; rewrite gtn_eqF//= jE (leq_trans (ltn_ord l))// leq_addr.
- congr (g w i _); apply/val_inj => /=.
by apply/eqP; rewrite -(eqn_add2l n1) -lE -jE.
Qed.

Global Instance is_derive_row_mx f A g B x v :
is_derive x v f A -> is_derive x v g B ->
is_derive x v (fun t => row_mx (f t) (g t)) (row_mx A B).
Proof.
move=> [dfx fA] [dgx gB]; apply: DeriveDef; first exact: derivable_row_mx.
by rewrite derive_row_mx// fA gB.
Qed.

End derivable_derive_row_mx.

Lemma eqo_row_mx (K : realFieldType) {m n1 n2 : nat} (F : filter_on K)
(A1 : K -> 'M[K]_(m, n1)) (A2 : K -> 'M[K]_(m, n2)) :
(fun t => row_mx ([o_F id of A1] t) ([o_F id of A2] t)) =o_F id.
Proof.
apply/eqoP => _/posnumP[e]; near=> x; rewrite norm_row_mx ge_max.
by apply/andP; split; near: x; apply: littleoP.
Unshelve. all: by end_near. Qed.

(* NB: this could be moved earlier in the file hierarchy *)
Lemma cvg_row_mx {T : realFieldType} {F : set_system T} {n1 n2 : nat}
(G : 'rV[T]_n1) (H : 'rV[T]_n2) : Filter F ->
forall (f : T -> 'rV[T]_n1) (g : T -> 'rV[T]_n2),
f x @[x --> F] --> G -> g x @[x --> F] --> H ->
row_mx (f x) (g x) @[x --> F] --> row_mx G H.
Proof.
move=> FF M N cvgM cvgN; apply/cvgrPdist_le => /= e e0; near=> t.
rewrite sub_row_mx norm_row_mx ge_max; apply/andP; split.
- by near: t; move/cvgrPdist_le : cvgM => /(_ _ e0).
- by near: t; move/cvgrPdist_le : cvgN => /(_ _ e0).
Unshelve. all: by end_near. Qed.

Section is_diff_row_mx.
Local Open Scope classical_set_scope.
Context {R : realFieldType} {n1 n2 : nat}.
Implicit Types (M dM : R -> 'rV[R]_n1) (N dN : R -> 'rV[R]_n2) (x t : R).

Fact drow_mx M N x : differentiable M x -> differentiable N x ->
continuous (fun y => row_mx ('d M x y) ('d N x y)) /\
(fun y => row_mx (M y) (N y)) \o shift x = cst (row_mx (M x) (N x)) +
(fun y => row_mx ('d M x y) ('d N x y)) +o_ 0 id.
Proof.
move=> df dg; split=> [/= ?|].
by apply: cvg_row_mx => //=; exact: diff_continuous.
apply/eqaddoE; rewrite funeqE => y /=.
rewrite ![_ (_ + x)]diff_locallyx//.
have ->/= : forall h e, row_mx (M x + 'd M x y + [o_ 0 id of h] y)
(N x + 'd N x y + [o_ 0 id of e] y) =
row_mx (M x) (N x) + row_mx ('d M x y) ('d N x y) +
row_mx ([o_ 0 id of h] y) ([o_ 0 id of e] y).
by move=> /= h e; rewrite !add_row_mx.
congr (_ + _).
by rewrite -[LHS]/((fun y => row_mx (_ y) (_ y)) y) eqo_row_mx.
Qed.

Lemma diff_row_mx M N x : differentiable M x -> differentiable N x ->
'd (fun y => row_mx (M y) (N y)) x =
(fun y => row_mx ('d M x y) ('d N x y)) :> (R -> 'rV[R]_(n1 + n2)).
Proof.
move=> df dg.
pose d y := row_mx ('d M x y) ('d N x y).
have lin_row_mx : linear d.
by move=> /= a b c; rewrite /d 2!linearPZ scale_row_mx add_row_mx.
pose row_mxlM := GRing.isLinear.Build _ _ _ _ _ lin_row_mx.
pose row_mxL : {linear _ -> _} := HB.pack d row_mxlM.
rewrite -/d -[d]/(row_mxL : _ -> _).
by apply: diff_unique; have [] := drow_mx df dg.
Qed.

Lemma differentiable_row_mx M N x : differentiable M x -> differentiable N x ->
differentiable (fun t => row_mx (M t) (N t)) x.
Proof.
by move=> df dg; apply/diff_locallyP; rewrite diff_row_mx //; apply: drow_mx.
Qed.

Global Instance is_diff_row_mx M dM N dN x :
is_diff x M dM -> is_diff x N dN ->
is_diff x (fun t => row_mx (M t) (N t)) (fun t => row_mx (dM t) (dN t)).
Proof.
move=> dfx dgx; apply: DiffDef; first exact: differentiable_row_mx.
by rewrite diff_row_mx// !diff_val.
Qed.

End is_diff_row_mx.
54 changes: 53 additions & 1 deletion theories/normedtype_theory/matrix_normedtype.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
From HB Require Import structures.
From mathcomp Require Import all_ssreflect_compat finmap ssralg ssrnum matrix.
From mathcomp Require Import interval interval_inference.
From mathcomp Require Import boolp classical_sets reals topology.
From mathcomp Require Import boolp contra classical_sets reals topology.
From mathcomp Require Import prodnormedzmodule tvs pseudometric_normed_Zmodule.
From mathcomp Require Import normed_module.

Expand Down Expand Up @@ -274,3 +274,55 @@ split => [cf x|cf i j v].
apply: le_trans (le_bigmax _ _ (i, j)).
by rewrite !mxE.
Unshelve. all: by end_near. Qed.

Section norm_row_mx.
Context {K : realDomainType} {m n1 n2 : nat}.
Implicit Types (M : 'M[K]_(m, n1)) (N : 'M[K]_(m, n2)).

Lemma norm_row_mx0r M : `|row_mx M (0 : 'M_(m, n2))| = `|M|.
Proof.
apply/eqP; rewrite eq_le; apply/andP; split.
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
rewrite mxE; case: splitP => k kE; last by rewrite mxE normr0.
by rewrite [leRHS]/Num.norm/= !mx_normrE/= (le_bigmax _ _ (i, k)).
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
rewrite [leRHS]/Num.norm/= !mx_normrE/=.
rewrite (le_trans _(le_bigmax _ _ (i, lshift n2 j)))// mxE/=.
case: splitP => // k kE.
rewrite (_ : j = k)//; apply: val_inj => /=.
by apply/eqP; rewrite -(eqn_add2l n1) -kE.
absurd: kE.
by rewrite ltn_eqF// (leq_trans (ltn_ord j))// /lshift/= leq_addr.
Qed.

Lemma norm_row_mx0l N : `|row_mx (0 : 'M_(m, n1)) N| = `|N|.
Proof.
apply/eqP; rewrite eq_le; apply/andP; split.
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
rewrite mxE; case: splitP => k kE; first by rewrite mxE normr0.
by rewrite [leRHS]/Num.norm/= !mx_normrE/= (le_bigmax _ _ (i, k)).
- rewrite [leLHS]/Num.norm/= !mx_normrE/=; apply/bigmax_le => // -[i j]/= _.
rewrite [leRHS]/Num.norm/= !mx_normrE/=.
rewrite (le_trans _ (le_bigmax _ _ (i, rshift n1 j)))// mxE/=.
case: splitP => // k kE.
absurd: kE.
by rewrite gtn_eqF// (leq_trans (ltn_ord k))// /rshift/= leq_addr.
rewrite (_ : j = k)//; apply: val_inj => /=.
by apply/eqP; rewrite -(eqn_add2l n1) -kE.
Qed.

Lemma norm_row_mx M N : `|row_mx M N| = Num.max `|M| `|N|.
Proof.
apply/eqP; rewrite eq_le; apply/andP; split.
- rewrite [leLHS]/Num.norm/= !mx_normrE bigmax_le//= => -[i j] _/=.
rewrite le_max mxE; case: splitP => k kE.
+ by rewrite [in `|M|]/Num.norm/= !mx_normrE (le_bigmax _ _ (i, k)).
+ by rewrite [in `|N|]/Num.norm/= !mx_normrE (le_bigmax _ _ (i, k)) ?orbT.
- rewrite ge_max; apply/andP; split;
rewrite [leLHS]/Num.norm/= !mx_normrE bigmax_le//= => -[i j] _/=;
rewrite [leRHS]/Num.norm/= !mx_normrE.
+ by rewrite -(row_mxEl _ N)/= (le_bigmax _ _ (i, lshift n2 j)).
+ by rewrite -(row_mxEr M)/= (le_bigmax _ _ (i, rshift n1 j)).
Qed.

End norm_row_mx.
Loading