diff --git a/thys/Matrices_for_ODEs/MTX_Flows.thy b/thys/Matrices_for_ODEs/MTX_Flows.thy --- a/thys/Matrices_for_ODEs/MTX_Flows.thy +++ b/thys/Matrices_for_ODEs/MTX_Flows.thy @@ -1,291 +1,291 @@ (* Title: Affine systems of ODEs Author: Jonathan Julián Huerta y Munive, 2020 Maintainer: Jonathan Julián Huerta y Munive *) section \ Affine systems of ODEs \ -text \Affine systems of ordinary differential equations (ODEs) are those whose vector -fields are linear operators. Broadly speaking, if there are functions $A$ and $B$ such that the +text \Affine systems of ordinary differential equations (ODEs) are those whose vector +fields are linear operators. Broadly speaking, if there are functions $A$ and $B$ such that the system of ODEs $X'\, t = f\, (X\, t)$ turns into $X'\, t = (A\, t)\cdot (X\, t)+(B\, t)$, then it -is affine. The end goal of this section is to prove that every affine system of ODEs has a unique +is affine. The end goal of this section is to prove that every affine system of ODEs has a unique solution, and to obtain a characterization of said solution. \ theory MTX_Flows imports SQ_MTX "Hybrid_Systems_VCs.HS_ODEs" begin subsection \ Existence and uniqueness for affine systems \ -definition matrix_continuous_on :: "real set \ (real \ ('a::real_normed_algebra_1)^'n^'m) \ bool" +definition matrix_continuous_on :: "real set \ (real \ ('a::real_normed_algebra_1)^'n^'m) \ bool" where "matrix_continuous_on T A = (\t \ T. \\ > 0. \ \ > 0. \\\T. \\ - t\ < \ \ \A \ - A t\\<^sub>o\<^sub>p \ \)" lemma continuous_on_matrix_vector_multl: assumes "matrix_continuous_on T A" shows "continuous_on T (\t. A t *v s)" proof(rule continuous_onI, simp add: dist_norm) fix e t::real assume "0 < e" and "t \ T" let ?\ = "e/(\(if s = 0 then 1 else s)\)" have "?\ > 0" - using \0 < e\ by simp + using \0 < e\ by simp then obtain \ where dHyp: "\ > 0 \ (\\\T. \\ - t\ < \ \ \A \ - A t\\<^sub>o\<^sub>p \ ?\)" using assms \t \ T\ unfolding dist_norm matrix_continuous_on_def by fastforce {fix \ assume "\ \ T" and "\\ - t\ < \" have obs: "?\ * (\s\) = (if s = 0 then 0 else e)" by auto have "\A \ *v s - A t *v s\ = \(A \ - A t) *v s\" - by (simp add: matrix_vector_mult_diff_rdistrib) + by (simp add: matrix_vector_mult_diff_rdistrib) also have "... \ (\A \ - A t\\<^sub>o\<^sub>p) * (\s\)" using norm_matrix_le_mult_op_norm by blast also have "... \ ?\ * (\s\)" - using dHyp \\ \ T\ \\\ - t\ < \\ mult_right_mono norm_ge_zero by blast + using dHyp \\ \ T\ \\\ - t\ < \\ mult_right_mono norm_ge_zero by blast finally have "\A \ *v s - A t *v s\ \ e" by (subst (asm) obs) (metis (mono_tags, hide_lams) \0 < e\ less_eq_real_def order_trans)} thus "\d>0. \\\T. \\ - t\ < d \ \A \ *v s - A t *v s\ \ e" using dHyp by blast qed lemma lipschitz_cond_affine: fixes A :: "real \ 'a::real_normed_algebra_1^'n^'m" and T::"real set" defines "L \ Sup {\A t\\<^sub>o\<^sub>p |t. t \ T}" assumes "t \ T" and "bdd_above {\A t\\<^sub>o\<^sub>p |t. t \ T}" shows "\A t *v x - A t *v y\ \ L * (\x - y\)" proof- have obs: "\A t\\<^sub>o\<^sub>p \ Sup {\A t\\<^sub>o\<^sub>p |t. t \ T}" apply(rule cSup_upper) using continuous_on_subset assms by (auto simp: dist_norm) have "\A t *v x - A t *v y\ = \A t *v (x - y)\" by (simp add: matrix_vector_mult_diff_distrib) also have "... \ (\A t\\<^sub>o\<^sub>p) * (\x - y\)" using norm_matrix_le_mult_op_norm by blast also have "... \ Sup {\A t\\<^sub>o\<^sub>p |t. t \ T} * (\x - y\)" - using obs mult_right_mono norm_ge_zero by blast + using obs mult_right_mono norm_ge_zero by blast finally show "\A t *v x - A t *v y\ \ L * (\x - y\)" unfolding assms . qed lemma local_lipschitz_affine: fixes A :: "real \ 'a::real_normed_algebra_1^'n^'m" - assumes "open T" and "open S" + assumes "open T" and "open S" and Ahyp: "\\ \. \ > 0 \ \ \ T \ cball \ \ \ T \ bdd_above {\A t\\<^sub>o\<^sub>p |t. t \ cball \ \}" shows "local_lipschitz T S (\t s. A t *v s + B t)" proof(unfold local_lipschitz_def lipschitz_on_def, clarsimp) fix s t assume "s \ S" and "t \ T" then obtain e1 e2 where "cball t e1 \ T" and "cball s e2 \ S" and "min e1 e2 > 0" using open_cballE[OF _ \open T\] open_cballE[OF _ \open S\] by force hence obs: "cball t (min e1 e2) \ T" by auto let ?L = "Sup {\A \\\<^sub>o\<^sub>p |\. \ \ cball t (min e1 e2)}" have "\A t\\<^sub>o\<^sub>p \ {\A \\\<^sub>o\<^sub>p |\. \ \ cball t (min e1 e2)}" using \min e1 e2 > 0\ by auto moreover have bdd: "bdd_above {\A \\\<^sub>o\<^sub>p |\. \ \ cball t (min e1 e2)}" by (rule Ahyp, simp only: \min e1 e2 > 0\, simp_all add: \t \ T\ obs) moreover have "Sup {\A \\\<^sub>o\<^sub>p |\. \ \ cball t (min e1 e2)} \ 0" apply(rule order.trans[OF op_norm_ge_0[of "A t"]]) by (rule cSup_upper[OF calculation]) - moreover have "\x\cball s (min e1 e2) \ S. \y\cball s (min e1 e2) \ S. + moreover have "\x\cball s (min e1 e2) \ S. \y\cball s (min e1 e2) \ S. \\\cball t (min e1 e2) \ T. dist (A \ *v x) (A \ *v y) \ ?L * dist x y" apply(clarify, simp only: dist_norm, rule lipschitz_cond_affine) using \min e1 e2 > 0\ bdd by auto - ultimately show "\e>0. \L. \t\cball t e \ T. 0 \ L \ + ultimately show "\e>0. \L. \t\cball t e \ T. 0 \ L \ (\x\cball s e \ S. \y\cball s e \ S. dist (A t *v x) (A t *v y) \ L * dist x y)" using \min e1 e2 > 0\ by blast qed lemma picard_lindeloef_affine: fixes A :: "real \ 'a::{banach,real_normed_algebra_1,heine_borel}^'n^'n" assumes Ahyp: "matrix_continuous_on T A" and "\\ \. \ \ T \ \ > 0 \ bdd_above {\A t\\<^sub>o\<^sub>p |t. dist \ t \ \}" - and Bhyp: "continuous_on T B" and "open S" - and "t\<^sub>0 \ T" and Thyp: "open T" "is_interval T" + and Bhyp: "continuous_on T B" and "open S" + and "t\<^sub>0 \ T" and Thyp: "open T" "is_interval T" shows "picard_lindeloef (\ t s. A t *v s + B t) T S t\<^sub>0" apply (unfold_locales, simp_all add: assms, clarsimp) apply (rule continuous_on_add[OF continuous_on_matrix_vector_multl[OF Ahyp] Bhyp]) by (rule local_lipschitz_affine) (simp_all add: assms) -lemma picard_lindeloef_autonomous_affine: +lemma picard_lindeloef_autonomous_affine: fixes A :: "'a::{banach,real_normed_field,heine_borel}^'n^'n" shows "picard_lindeloef (\ t s. A *v s + B) UNIV UNIV t\<^sub>0" - using picard_lindeloef_affine[of _ "\t. A" "\t. B"] + using picard_lindeloef_affine[of _ "\t. A" "\t. B"] unfolding matrix_continuous_on_def by (simp only: diff_self op_norm0, auto) lemma picard_lindeloef_autonomous_linear: fixes A :: "'a::{banach,real_normed_field,heine_borel}^'n^'n" shows "picard_lindeloef (\ t. (*v) A) UNIV UNIV t\<^sub>0" using picard_lindeloef_autonomous_affine[of A 0] by force -lemmas unique_sol_autonomous_affine = picard_lindeloef.unique_solution[OF +lemmas unique_sol_autonomous_affine = picard_lindeloef.unique_solution[OF picard_lindeloef_autonomous_affine _ _ funcset_UNIV UNIV_I _ _ funcset_UNIV UNIV_I] -lemmas unique_sol_autonomous_linear = picard_lindeloef.unique_solution[OF +lemmas unique_sol_autonomous_linear = picard_lindeloef.unique_solution[OF picard_lindeloef_autonomous_linear _ _ funcset_UNIV UNIV_I _ _ funcset_UNIV UNIV_I] subsection \ Flow for affine systems \ subsubsection \ Derivative rules for square matrices \ lemma has_derivative_exp_scaleRl[derivative_intros]: fixes f::"real \ real" (* by Fabian Immler and Johannes Hölzl *) assumes "D f \ f' at t within T" shows "D (\t. exp (f t *\<^sub>R A)) \ (\h. f' h *\<^sub>R (exp (f t *\<^sub>R A) * A)) at t within T" proof - - have "bounded_linear f'" + have "bounded_linear f'" using assms by auto then obtain m where obs: "f' = (\h. h * m)" using real_bounded_linear by blast thus ?thesis - using vector_diff_chain_within[OF _ exp_scaleR_has_vector_derivative_right] + using vector_diff_chain_within[OF _ exp_scaleR_has_vector_derivative_right] assms obs by (auto simp: has_vector_derivative_def comp_def) qed lemma has_vderiv_on_exp_scaleRl: assumes "D f = f' on T" shows "D (\x. exp (f x *\<^sub>R A)) = (\x. f' x *\<^sub>R exp (f x *\<^sub>R A) * A) on T" using assms unfolding has_vderiv_on_def has_vector_derivative_def apply clarsimp by (rule has_derivative_exp_scaleRl, auto simp: fun_eq_iff) lemma vderiv_on_exp_scaleRlI[poly_derivatives]: assumes "D f = f' on T" and "g' = (\x. f' x *\<^sub>R exp (f x *\<^sub>R A) * A)" shows "D (\x. exp (f x *\<^sub>R A)) = g' on T" using has_vderiv_on_exp_scaleRl assms by simp lemma has_derivative_mtx_ith[derivative_intros]: fixes t::real and T :: "real set" defines "t\<^sub>0 \ netlimit (at t within T)" assumes "D A \ (\h. h *\<^sub>R A' t) at t within T" shows "D (\t. A t $$ i) \ (\h. h *\<^sub>R A' t $$ i) at t within T" using assms unfolding has_derivative_def apply safe apply(force simp: bounded_linear_def bounded_linear_axioms_def) apply(rule_tac F="\\. (A \ - A t\<^sub>0 - (\ - t\<^sub>0) *\<^sub>R A' t) /\<^sub>R (\\ - t\<^sub>0\)" in tendsto_zero_norm_bound) - by (clarsimp, rule mult_left_mono, metis (no_types, lifting) norm_column_le_norm + by (clarsimp, rule mult_left_mono, metis (no_types, lifting) norm_column_le_norm sq_mtx_minus_ith sq_mtx_scaleR_ith) simp_all -lemmas has_derivative_mtx_vec_mult[derivative_intros] = +lemmas has_derivative_mtx_vec_mult[derivative_intros] = bounded_bilinear.FDERIV[OF bounded_bilinear_sq_mtx_vec_mult] lemma vderiv_mtx_vec_mult_intro[poly_derivatives]: assumes "D u = u' on T" and "D A = A' on T" and "g = (\t. A t *\<^sub>V u' t + A' t *\<^sub>V u t )" shows "D (\t. A t *\<^sub>V u t) = g on T" using assms unfolding has_vderiv_on_def has_vector_derivative_def apply clarsimp apply(erule_tac x=x in ballE, simp_all)+ - apply(rule derivative_eq_intros(142)) + apply(rule derivative_eq_intros) by (auto simp: fun_eq_iff mtx_vec_scaleR_commute pth_6 scaleR_mtx_vec_assoc) lemmas has_vderiv_on_ivl_integral = ivl_integral_has_vderiv_on[OF vderiv_on_continuous_on] declare has_vderiv_on_ivl_integral [poly_derivatives] lemma has_derivative_mtx_vec_multl[derivative_intros]: assumes "\ i j. D (\t. (A t) $$ i $ j) \ (\\. \ *\<^sub>R (A' t) $$ i $ j) (at t within T)" shows "D (\t. A t *\<^sub>V x) \ (\\. \ *\<^sub>R (A' t) *\<^sub>V x) at t within T" unfolding sq_mtx_vec_mult_sum_cols apply(rule_tac f'1="\i \. \ *\<^sub>R (x $ i *\<^sub>R \\\ i (A' t))" in derivative_eq_intros(10)) apply(simp_all add: scaleR_right.sum) apply(rule_tac g'1="\\. \ *\<^sub>R \\\ i (A' t)" in derivative_eq_intros(4), simp_all add: mult.commute) using assms unfolding sq_mtx_col_def column_def apply(transfer, simp) apply(rule has_derivative_vec_lambda) by (simp add: scaleR_vec_def) lemma continuous_on_mtx_vec_multr: "continuous_on S ((*\<^sub>V) A)" by transfer (simp add: matrix_vector_mult_linear_continuous_on) \ \Automatically generated derivative rules from this subsubsection \ thm derivative_eq_intros(140,141,142,143) subsubsection \ Existence and uniqueness with square matrices \ -text \Finally, we can use the @{term exp} operation to characterize the general solutions for affine +text \Finally, we can use the @{term exp} operation to characterize the general solutions for affine systems of ODEs. We show that they satisfy the @{term "local_flow"} locale.\ lemma continuous_on_sq_mtx_vec_multl: fixes A :: "real \ ('n::finite) sq_mtx" assumes "continuous_on T A" shows "continuous_on T (\t. A t *\<^sub>V s)" proof- have "matrix_continuous_on T (\t. to_vec (A t))" using assms by (force simp: continuous_on_iff dist_norm norm_sq_mtx_def matrix_continuous_on_def) hence "continuous_on T (\t. to_vec (A t) *v s)" by (rule continuous_on_matrix_vector_multl) thus ?thesis by transfer qed lemmas continuous_on_affine = continuous_on_add[OF continuous_on_sq_mtx_vec_multl] lemma local_lipschitz_sq_mtx_affine: fixes A :: "real \ ('n::finite) sq_mtx" assumes "continuous_on T A" "open T" "open S" shows "local_lipschitz T S (\t s. A t *\<^sub>V s + B t)" proof- have obs: "\\ \. 0 < \ \ \ \ T \ cball \ \ \ T \ bdd_above {\A t\ |t. t \ cball \ \}" by (rule bdd_above_norm_cont_comp, rule continuous_on_subset[OF assms(1)], simp_all) hence "\\ \. 0 < \ \ \ \ T \ cball \ \ \ T \ bdd_above {\to_vec (A t)\\<^sub>o\<^sub>p |t. t \ cball \ \}" by (simp add: norm_sq_mtx_def) hence "local_lipschitz T S (\t s. to_vec (A t) *v s + B t)" using local_lipschitz_affine[OF assms(2,3), of "\t. to_vec (A t)"] by force thus ?thesis - by transfer + by transfer qed lemma picard_lindeloef_sq_mtx_affine: - assumes "continuous_on T A" and "continuous_on T B" + assumes "continuous_on T A" and "continuous_on T B" and "t\<^sub>0 \ T" "is_interval T" "open T" and "open S" shows "picard_lindeloef (\t s. A t *\<^sub>V s + B t) T S t\<^sub>0" apply(unfold_locales, simp_all add: assms, clarsimp) using continuous_on_affine assms apply blast by (rule local_lipschitz_sq_mtx_affine, simp_all add: assms) -lemmas sq_mtx_unique_sol_autonomous_affine = picard_lindeloef.unique_solution[OF - picard_lindeloef_sq_mtx_affine[OF - continuous_on_const - continuous_on_const - UNIV_I is_interval_univ - open_UNIV open_UNIV] +lemmas sq_mtx_unique_sol_autonomous_affine = picard_lindeloef.unique_solution[OF + picard_lindeloef_sq_mtx_affine[OF + continuous_on_const + continuous_on_const + UNIV_I is_interval_univ + open_UNIV open_UNIV] _ _ funcset_UNIV UNIV_I _ _ funcset_UNIV UNIV_I] lemma has_vderiv_on_sq_mtx_linear: "D (\t. exp ((t - t\<^sub>0) *\<^sub>R A) *\<^sub>V s) = (\t. A *\<^sub>V (exp ((t - t\<^sub>0) *\<^sub>R A) *\<^sub>V s)) on {t\<^sub>0--t}" by (rule poly_derivatives)+ (auto simp: exp_times_scaleR_commute sq_mtx_times_vec_assoc) lemma has_vderiv_on_sq_mtx_affine: fixes t\<^sub>0::real and A :: "('a::finite) sq_mtx" defines "lSol c t \ exp ((c * (t - t\<^sub>0)) *\<^sub>R A)" - shows "D (\t. lSol 1 t *\<^sub>V s + lSol 1 t *\<^sub>V (\\<^sub>t\<^sub>0\<^sup>t (lSol (-1) \ *\<^sub>V B) \\)) = + shows "D (\t. lSol 1 t *\<^sub>V s + lSol 1 t *\<^sub>V (\\<^sub>t\<^sub>0\<^sup>t (lSol (-1) \ *\<^sub>V B) \\)) = (\t. A *\<^sub>V (lSol 1 t *\<^sub>V s + lSol 1 t *\<^sub>V (\\<^sub>t\<^sub>0\<^sup>t (lSol (-1) \ *\<^sub>V B) \\)) + B) on {t\<^sub>0--t}" unfolding assms apply(simp only: mult.left_neutral mult_minus1) apply(rule poly_derivatives, (force)?, (force)?, (force)?, (force)?)+ - by (simp add: mtx_vec_mult_add_rdistl sq_mtx_times_vec_assoc[symmetric] + by (simp add: mtx_vec_mult_add_rdistl sq_mtx_times_vec_assoc[symmetric] exp_minus_inverse exp_times_scaleR_commute mult_exp_exp scale_left_distrib[symmetric]) lemma autonomous_linear_sol_is_exp: - assumes "D X = (\t. A *\<^sub>V X t) on {t\<^sub>0--t}" and "X t\<^sub>0 = s" + assumes "D X = (\t. A *\<^sub>V X t) on {t\<^sub>0--t}" and "X t\<^sub>0 = s" shows "X t = exp ((t - t\<^sub>0) *\<^sub>R A) *\<^sub>V s" apply(rule sq_mtx_unique_sol_autonomous_affine[of X A 0, OF _ \X t\<^sub>0 = s\]) using assms has_vderiv_on_sq_mtx_linear by force+ lemma autonomous_affine_sol_is_exp_plus_int: - assumes "D X = (\t. A *\<^sub>V X t + B) on {t\<^sub>0--t}" and "X t\<^sub>0 = s" + assumes "D X = (\t. A *\<^sub>V X t + B) on {t\<^sub>0--t}" and "X t\<^sub>0 = s" shows "X t = exp ((t - t\<^sub>0) *\<^sub>R A) *\<^sub>V s + exp ((t - t\<^sub>0) *\<^sub>R A) *\<^sub>V (\\<^sub>t\<^sub>0\<^sup>t(exp (- (\ - t\<^sub>0) *\<^sub>R A) *\<^sub>V B)\\)" apply(rule sq_mtx_unique_sol_autonomous_affine[OF assms]) using has_vderiv_on_sq_mtx_affine by force+ lemma local_flow_sq_mtx_linear: "local_flow ((*\<^sub>V) A) UNIV UNIV (\t s. exp (t *\<^sub>R A) *\<^sub>V s)" unfolding local_flow_def local_flow_axioms_def apply safe using picard_lindeloef_sq_mtx_affine[of _ "\t. A" "\t. 0"] apply force using has_vderiv_on_sq_mtx_linear[of 0] by auto -lemma local_flow_sq_mtx_affine: "local_flow (\s. A *\<^sub>V s + B) UNIV UNIV +lemma local_flow_sq_mtx_affine: "local_flow (\s. A *\<^sub>V s + B) UNIV UNIV (\t s. exp (t *\<^sub>R A) *\<^sub>V s + exp (t *\<^sub>R A) *\<^sub>V (\\<^sub>0\<^sup>t(exp (- \ *\<^sub>R A) *\<^sub>V B)\\))" unfolding local_flow_def local_flow_axioms_def apply safe using picard_lindeloef_sq_mtx_affine[of _ "\t. A" "\t. B"] apply force using has_vderiv_on_sq_mtx_affine[of 0 A] by auto end \ No newline at end of file