Built with
Alectryon , running Coq+SerAPI v8.15.0+0.15.0. Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents. Use
Ctrl+↑ Ctrl+↓ to navigate,
Ctrl+🖱️ to focus. On Mac, use
⌘ instead of
Ctrl .
(* mathcomp analysis (c) 2017 Inria and AIST. License: CeCILL-C. *)
From mathcomp Require Import all_ssreflect ssralg ssrint ssrnum matrix.Notation "[ predI _ & _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]Notation "[ predU _ & _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]Notation "[ predD _ & _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]Notation "[ predC _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]Notation "[ preim _ of _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]Notation "_ + _" was already used in scope nat_scope.
[notation-overridden,parsing]Notation "_ - _" was already used in scope nat_scope.
[notation-overridden,parsing]Notation "_ <= _" was already used in scope nat_scope.
[notation-overridden,parsing]Notation "_ < _" was already used in scope nat_scope.
[notation-overridden,parsing]Notation "_ >= _" was already used in scope nat_scope.
[notation-overridden,parsing]Notation "_ > _" was already used in scope nat_scope.
[notation-overridden,parsing]Notation "_ <= _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing]Notation "_ < _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing]Notation "_ <= _ < _" was already used in scope
nat_scope. [notation-overridden,parsing]Notation "_ < _ < _" was already used in scope
nat_scope. [notation-overridden,parsing]Notation "_ * _" was already used in scope nat_scope.
[notation-overridden,parsing]New coercion path [GRing.subring_closedM;
GRing.smulr_closedN] : GRing.subring_closed >-> GRing.oppr_closed is ambiguous with existing
[GRing.subring_closedB; GRing.zmod_closedN] : GRing.subring_closed >-> GRing.oppr_closed.
[ambiguous-paths,typechecker] New coercion path [GRing.subring_closed_semi;
GRing.semiring_closedM] : GRing.subring_closed >-> GRing.mulr_closed is ambiguous with existing
[GRing.subring_closedM; GRing.smulr_closedM] : GRing.subring_closed >-> GRing.mulr_closed.
New coercion path [GRing.subring_closed_semi;
GRing.semiring_closedD] : GRing.subring_closed >-> GRing.addr_closed is ambiguous with existing
[GRing.subring_closedB; GRing.zmod_closedD] : GRing.subring_closed >-> GRing.addr_closed.
[ambiguous-paths,typechecker] New coercion path [GRing.sdivr_closed_div;
GRing.divr_closedM] : GRing.sdivr_closed >-> GRing.mulr_closed is ambiguous with existing
[GRing.sdivr_closedM; GRing.smulr_closedM] : GRing.sdivr_closed >-> GRing.mulr_closed.
[ambiguous-paths,typechecker] New coercion path [GRing.subalg_closedBM;
GRing.subring_closedB] : GRing.subalg_closed >-> GRing.zmod_closed is ambiguous with existing
[GRing.subalg_closedZ; GRing.submod_closedB] : GRing.subalg_closed >-> GRing.zmod_closed.
[ambiguous-paths,typechecker] New coercion path [GRing.divring_closed_div;
GRing.sdivr_closedM] : GRing.divring_closed >-> GRing.smulr_closed is ambiguous with existing
[GRing.divring_closedBM; GRing.subring_closedM] : GRing.divring_closed >-> GRing.smulr_closed.
[ambiguous-paths,typechecker] New coercion path [GRing.divalg_closedBdiv;
GRing.divring_closedBM] : GRing.divalg_closed >-> GRing.subring_closed is ambiguous with existing
[GRing.divalg_closedZ; GRing.subalg_closedBM] : GRing.divalg_closed >-> GRing.subring_closed.
[ambiguous-paths,typechecker] New coercion path [GRing.Pred.subring_smul;
GRing.Pred.smul_mul] : GRing.Pred.subring >-> GRing.Pred.mul is ambiguous with existing
[GRing.Pred.subring_semi; GRing.Pred.semiring_mul] : GRing.Pred.subring >-> GRing.Pred.mul.
[ambiguous-paths,typechecker]
From mathcomp Require Import interval rat.
From mathcomp.classical Require Import boolp classical_sets functions.
From mathcomp.classical Require Import mathcomp_extra.
Require Import reals ereal nsatz_realtype signed topology normedtype landau.
Require Import sequences derive realfun exp.
(******************************************************************************)
(* Theory of trigonometric functions *)
(* *)
(* This file provides the definitions of basic trigonometric functions and *)
(* develops their theories. *)
(* *)
(* periodic f T == f is a periodic function of period T *)
(* alternating f T == f is an alternating function of period T *)
(* sin_coeff x == the sequence of coefficients of sin x *)
(* sin x == the sine function, i.e., lim (series (sin_coeff x)) *)
(* sin_coeff' x == the sequence of odd coefficients of sin x *)
(* cos_coeff x == the sequence of coefficients of cos x *)
(* cos x == the cosine function, i.e., lim (series (cos_coeff x)) *)
(* cos_coeff' x == the sequence of even coefficients of cos x *)
(* pi == pi *)
(* tan x == the tangent function *)
(* acos x == the arccos function *)
(* asin x == the arcsin function *)
(* atan x == the arctangent function *)
(* *)
(* Acknowledgments: the proof of cos 2 < 0 is inspired from HOL-light, some *)
(* proofs of trigonometric relations are taken from *)
(* https://github.com/affeldt-aist/coq-robot. *)
(* *)
(******************************************************************************)
Set Implicit Arguments .
Unset Strict Implicit .
Unset Printing Implicit Defensive .
Import Order.TTheory GRing.Theory Num.Def Num.Theory.
Import numFieldNormedType.Exports.
Local Open Scope classical_set_scope.
Local Open Scope ring_scope.
(* NB: backport to mathcomp in progress *)
Lemma sqrtrV (R : rcfType) (x : R) : 0 <= x -> Num.sqrt (x^-1 ) = (Num.sqrt x)^-1 .
Proof .
move => x_ge0.
case : (x =P 0 ) => [->|/eqP xD0]; first by rewrite invr0 sqrtr0 invr0.
rewrite -[LHS]mul1r -(mulVf (_ : Num.sqrt x != 0 )); last first .
by rewrite sqrtr_eq0 -ltNge; case : ltrgt0P x_ge0 xD0.
by rewrite -mulrA -sqrtrM // divff // sqrtr1 mulr1.
Qed .
Lemma eqr_div (R : numFieldType) (x y z t : R):
y != 0 -> t != 0 -> (x / y == z / t) = (x * t == z * y).
Proof .
move => yD0 tD0.
rewrite -[x in RHS](divfK yD0) -[z in RHS](divfK tD0) mulrAC.
by apply /eqP/eqP=> [->//|xyty]; exact /(mulIf tD0)/(mulIf yD0).
Qed .
Lemma big_nat_mul (R : zmodType) (f : R ^nat) (n k : nat) :
\sum_(0 <= i < n * k) f i =
\sum_(0 <= i < n) \sum_(i * k <= j < i.+1 * k) f j.
Proof .
elim : n => [|n ih]; first by rewrite mul0n 2 !big_nil.
rewrite [in RHS]big_nat_recr//= -ih mulSn addnC [in LHS]/index_iota subn0 iotaD.
rewrite big_cat /= [in X in _ = X _]/index_iota subn0; congr (_ + _).
by rewrite add0n /index_iota (addnC _ k) addnK.
Qed .
(* /NB: backport to mathcomp in progress *)
Lemma cvg_series_cvg_series_group (R : realFieldType) (f : R ^nat) k :
cvg (series f) -> (0 < k)%N ->
[series \sum_(n * k <= i < n.+1 * k) f i]_n --> lim (series f).
Proof .
move => /cvg_ballP cf k0; apply /cvg_ballP => _/posnumP[e].
have := !! cf _ (gt0 e) => -[n _ nl]; near=> m.
rewrite /ball /= [in X in `|_ - X|]/series [in X in `|_ - X|]/= -big_nat_mul.
have /nl : (n <= m * k)%N.
by near: m; exists n .+1 => //= p /ltnW /leq_trans /(_ (leq_pmulr _ k0)).
by rewrite /ball /= distrC.
Unshelve . all : by end_near. Qed .
Lemma lt_sum_lim_series (R : realFieldType) (f : R ^nat) n : cvg (series f) ->
(forall d , 0 < f (n + d.*2 )%N + f (n + d.*2 .+1 )%N) ->
\sum_(0 <= i < n) f i < lim (series f).
Proof .
move => /cvg_ballP cf fn.
have fn0 : 0 < f n + f n.+1 by have := fn 0 %N; rewrite double0 addn0 addn1.
rewrite ltNge; apply : contraPN cf => ffn /(_ _ fn0).
have nf_ub N : \sum_(0 <= i < n.+2 ) f i <= \sum_(0 <= i < N.+1 .*2 + n) f i.
elim : N => // N /le_trans ->//; rewrite -(addn1 (N.+1 )) doubleD addnAC.
rewrite [in leRHS]/index_iota subn0 iotaD big_cat.
rewrite -[in X in _ <= X + _](subn0 (N.+1 .*2 + n)%N) ler_addl /= add0n.
by rewrite 2 !big_cons big_nil addr0 -(addnC n) ltW// -addnS fn.
case => N _ Nfn; have /Nfn/ltr_distlC_addr : (N.+1 .*2 + n >= N)%N.
by rewrite doubleS -addn2 -addnn -2 !addnA leq_addr.
rewrite addrA => ffnfn.
have : lim (series f) + f n + f n.+1 <= \sum_(0 <= i < N.+1 .*2 + n) f i.
apply : (le_trans _ (nf_ub N)).
by do 2 rewrite big_nat_recr //=; by rewrite -2 !addrA ler_add2r.
by move /(lt_le_trans ffnfn); rewrite ltxx.
Qed .
Section periodic .
Variables U V : zmodType.
Implicit Type f : U -> V.
Definition periodic f (T : U) := forall u , f (u + T) = f u.
Lemma periodicn f (T : U) : periodic f T -> forall n a , f (a + T *+ n) = f a.
Proof .
by move => fT; elim => [|n ih] a;[rewrite mulr0n addr0|rewrite mulrS addrA ih fT].
Qed .
End periodic .
Section alternating .
Variables (U : zmodType) (V : ringType).
Implicit Type f : U -> V.
Definition alternating f (T : U) := forall x , f (x + T) = - f x.
Lemma alternatingn f (T : U) : alternating f T ->
forall n a , f (a + T *+ n) = (- 1 ) ^+ n * f a.
Proof .
move => fT; elim => [a|n ih a]; first by rewrite mulr0n expr0 addr0 mul1r.
by rewrite mulrS addrA ih fT exprS mulrN mulN1r mulNr.
Qed .
End alternating .
Section CosSin .
Variable R : realType.
Implicit Types x y : R.
Definition sin_coeff x :=
[sequence (odd n)%:R * (-1 ) ^+ n.-1 ./2 * x ^+ n / n`!%:R]_n.
Lemma sin_coeffE x : sin_coeff x =
(fun n => (fun n => (odd n)%:R * (-1 ) ^+ n.-1 ./2 * (n`!%:R)^-1 ) n * x ^+ n).
Proof . by apply /funext => i; rewrite /sin_coeff /= -!mulrA [_ / _]mulrC. Qed .
Lemma sin_coeff_even n x : sin_coeff x n.*2 = 0 .
Proof . by rewrite /sin_coeff /= odd_double /= !mul0r. Qed .
Lemma is_cvg_series_sin_coeff x : cvg (series (sin_coeff x)).
Proof .
apply : normed_cvg.
apply : series_le_cvg; last exact : (@is_cvg_series_exp_coeff _ `|x|).
- by move => n; rewrite normr_ge0.
- by move => n; rewrite divr_ge0.
- move => n /=; rewrite /exp_coeff /sin_coeff /=.
rewrite !normrM normfV !normr_nat !normrX normrN normr1 expr1n mulr1.
by case : odd; [rewrite mul1r| rewrite !mul0r].
Qed .
Definition sin x : R := lim (series (sin_coeff x)).
Lemma sinE : sin = fun x =>
lim (pseries (fun n => (odd n)%:R * (-1 ) ^+ n.-1 ./2 * (n`!%:R)^-1 ) x).
Proof . by apply /funext => x; rewrite /pseries -sin_coeffE. Qed .
Definition sin_coeff' x (n : nat) := (-1 )^n * x ^+ n.*2 .+1 / n.*2 .+1 `!%:R.
Lemma sin_coeff'E x n : sin_coeff' x n = sin_coeff x n.*2 .+1 .
Proof .
by rewrite /sin_coeff' /sin_coeff /= odd_double mul1r -2 !mulrA doubleK.
Qed .
Lemma cvg_sin_coeff' x : series (sin_coeff' x) --> sin x.
Proof .
have /(@cvg_series_cvg_series_group _ _ 2 ) := @is_cvg_series_sin_coeff x.
move => /(_ isT); apply : cvg_trans.
rewrite [X in _ --> series X](_ : _ = (fun n => sin_coeff x n.*2 .+1 )).
rewrite [X in series X --> _](_ : _ = (fun n => sin_coeff x n.*2 .+1 )) //.
by rewrite funeqE => n; exact : sin_coeff'E.
rewrite funeqE=> n; rewrite /= 2 !muln2 big_nat_recl //= sin_coeff_even add0r.
by rewrite big_nat_recl // big_geq // addr0.
Qed .
Lemma diffs_sin :
pseries_diffs (fun n => (odd n)%:R * (-1 ) ^+ n.-1 ./2 * (n`!%:R)^-1 ) =
(fun n => (~~(odd n))%:R * (-1 ) ^+ n./2 * (n`!%:R)^-1 : R).
Proof .
apply /funext => i; rewrite /pseries_diffs /= factS natrM invfM.
by rewrite [_.+1 %:R * _]mulrC -!mulrA [_.+1 %:R^-1 * _]mulrC mulfK.
Qed .
Lemma series_sin_coeff0 n : series (sin_coeff 0 ) n.+1 = 0 .
Proof .
rewrite /series /= big_nat_recl //= /sin_coeff /= expr0n divr1 !mulr1.
by rewrite big1 ?addr0 // => i _; rewrite expr0n !(mul0r, mulr0).
Qed .
Lemma sin0 : sin 0 = 0 .
Proof .
apply : lim_near_cst => //; near=> m; rewrite -[m]prednK; last by near: m.
rewrite -addn1 series_addn series_sin_coeff0 big_add1 big1 ?addr0 //.
by move => i _; rewrite /sin_coeff /= expr0n !(mulr0, mul0r).
Unshelve . all : by end_near. Qed .
Definition cos_coeff x :=
[sequence (~~ odd n)%:R * (-1 )^n./2 * x ^+ n / n`!%:R]_n.
Lemma cos_coeff_odd n x : cos_coeff x n.*2 .+1 = 0 .
Proof . by rewrite /cos_coeff /= odd_double /= !mul0r. Qed .
Lemma cos_coeff_2_0 : cos_coeff 2 0 %N = 1 :> R.
Proof . by rewrite /cos_coeff /= mul1r expr0 mulr1 expr0z divff. Qed .
Lemma cos_coeff_2_2 : cos_coeff 2 2 %N = - 2 %:R :> R.
Proof .
by rewrite /cos_coeff /= mul1r expr1z mulN1r expr2 mulNr -mulrA divff// mulr1.
Qed .
Lemma cos_coeff_2_4 : cos_coeff 2 4 %N = 2 %:R / 3 %:R :> R.
Proof .
rewrite /cos_coeff /= mul1r -exprnP sqrrN expr1n mul1r 2 !factS mulnCA mulnC.
by rewrite 3 !exprS expr1 2 !mulrA natrM -mulf_div -2 !natrM divff// mul1r.
Qed .
Lemma cos_coeffE x :
cos_coeff x = (fun n => (fun n => (~~(odd n))%:R * (-1 ) ^+ n./2 *
(n`!%:R)^-1 ) n * x ^+ n).
Proof .
by apply /funext => i; rewrite /cos_coeff /= -!mulrA [_ / _]mulrC.
Qed .
Lemma is_cvg_series_cos_coeff x : cvg (series (cos_coeff x)).
Proof .
apply : normed_cvg.
apply : series_le_cvg; last exact : (@is_cvg_series_exp_coeff _ `|x|).
- by move => n; rewrite normr_ge0.
- by move => n; rewrite divr_ge0.
- move => n /=; rewrite /exp_coeff /cos_coeff /=.
rewrite !normrM normfV !normr_nat !normrX normrN normr1 expr1n mulr1.
by case : odd; [rewrite !mul0r | rewrite mul1r].
Qed .
Definition cos x : R := lim (series (cos_coeff x)).
Lemma cosE : cos = fun x =>
lim (series (fun n =>
(fun n => (~~(odd n))%:R * (-1 )^+ n./2 * (n`!%:R)^-1 ) n
* x ^+ n)).
Proof . by apply /funext => x; rewrite -cos_coeffE. Qed .
Definition cos_coeff' x (n : nat) := (-1 )^n * x ^+ n.*2 / n.*2 `!%:R.
Lemma cos_coeff'E x n : cos_coeff' x n = cos_coeff x n.*2 .
Proof .
rewrite /cos_coeff' /cos_coeff /= odd_double /= mul1r -2 !mulrA; congr (_ * _).
by rewrite (half_bit_double n false).
Qed .
Lemma cvg_cos_coeff' x : series (cos_coeff' x) --> cos x.
Proof .
have /(@cvg_series_cvg_series_group _ _ 2 ) := @is_cvg_series_cos_coeff x.
move => /(_ isT); apply : cvg_trans.
rewrite [X in _ --> series X](_ : _ = (fun n => cos_coeff x n.*2 )); last first .
rewrite funeqE=> n; rewrite /= 2 !muln2 big_nat_recr //= cos_coeff_odd addr0.
by rewrite big_nat_recl//= /index_iota subnn big_nil addr0.
rewrite [X in series X --> _](_ : _ = (fun n => cos_coeff x n.*2 )) //.
by rewrite funeqE => n; exact : cos_coeff'E.
Qed .
Lemma diffs_cos :
pseries_diffs (fun n => (~~(odd n))%:R * (-1 ) ^+ n./2 * (n`!%:R)^-1 ) =
(fun n => - ((odd n)%:R * (-1 ) ^+ n.-1 ./2 * (n`!%:R)^-1 ): R).
Proof .
apply /funext => [] [|i] /=.
by rewrite /pseries_diffs /= !mul0r mulr0 oppr0.
rewrite /pseries_diffs /= negbK exprS mulN1r !(mulNr, mulrN).
rewrite factS natrM invfM.
by rewrite [_.+1 %:R * _]mulrC -!mulrA [_.+1 %:R^-1 * _]mulrC mulfK.
Qed .
Lemma series_cos_coeff0 n : series (cos_coeff 0 ) n.+1 = 1 .
Proof .
rewrite /series /= big_nat_recl //= /cos_coeff /= expr0n divr1 !mulr1.
by rewrite big1 ?addr0 // => i _; rewrite expr0n !(mul0r, mulr0).
Qed .
Lemma cos0 : cos 0 = 1 .
Proof .
apply : lim_near_cst => //; near=> m; rewrite -[m]prednK; last by near: m.
rewrite -addn1 series_addn series_cos_coeff0 big_add1 big1 ?addr0 //.
by move => i _; rewrite /cos_coeff /= expr0n !(mulr0, mul0r).
Unshelve . all : by end_near. Qed .
Global Instance is_derive_sin x : is_derive x 1 sin (cos x).
Proof .
rewrite sinE /=.
pose s : R^nat := fun n => (odd n)%:R * (-1 ) ^+ (n.-1 )./2 / n`!%:R.
pose s1 n := pseries_diffs s n * x ^+ n.
rewrite cosE /= /pseries (_ : (fun _ => _) = s1); last first .
by apply /funext => i; rewrite /s1 diffs_sin.
apply : (@pseries_snd_diffs _ _ (`|x| + 1 )); rewrite /pseries.
- by rewrite -sin_coeffE; apply : is_cvg_series_sin_coeff.
- rewrite (_ : (fun _ => _) = cos_coeff (`|x| + 1 )).
exact : is_cvg_series_cos_coeff.
by apply /funext => i; rewrite diffs_sin cos_coeffE.
- rewrite /pseries (_ : (fun _ => _) = - sin_coeff (`|x| + 1 )).
by rewrite is_cvg_seriesN; exact : is_cvg_series_sin_coeff.
by apply /funext => i; rewrite diffs_sin diffs_cos sin_coeffE !fctE !mulNr.
- by rewrite [ltRHS]ger0_norm// addrC -subr_gt0 addrK.
Qed .
Lemma derivable_sin x : derivable sin x 1 .
Proof . by apply : ex_derive; apply : is_derive_sin. Qed .
Lemma continuous_sin : continuous sin.
Proof .
by move => x; apply /differentiable_continuous/derivable1_diffP/derivable_sin.
Qed .
Global Instance is_derive_cos x : is_derive x 1 cos (- (sin x)).
Proof .
rewrite cosE /=.
pose s : R^nat := fun n => (~~ odd n)%:R * (-1 ) ^+ n./2 / n`!%:R.
pose s1 n := pseries_diffs s n * x ^+ n.
rewrite sinE /= /pseries.
rewrite (_ : (fun _ => _) = - s1); last first .
by apply /funext => i; rewrite /s1 diffs_cos !fctE mulNr opprK.
rewrite lim_seriesN ?opprK ; last first .
rewrite (_ : s1 = - sin_coeff x).
by rewrite is_cvg_seriesN; exact : is_cvg_series_sin_coeff.
by apply /funext => i; rewrite /s1 diffs_cos sin_coeffE !fctE mulNr.
apply : (@pseries_snd_diffs _ _ (`|x| + 1 )).
- by rewrite /pseries -cos_coeffE; apply : is_cvg_series_cos_coeff.
- rewrite /pseries (_ : (fun _ => _) = - sin_coeff (`|x| + 1 )).
by rewrite is_cvg_seriesN; exact : is_cvg_series_sin_coeff.
by apply /funext => i; rewrite diffs_cos sin_coeffE !fctE mulNr.
- rewrite /pseries (_ : (fun _ => _) = - cos_coeff (`|x| + 1 )).
by rewrite is_cvg_seriesN; exact : is_cvg_series_cos_coeff.
apply /funext => i; rewrite diffs_cos pseries_diffsN.
by rewrite diffs_sin cos_coeffE mulNr.
- by rewrite [ltRHS]ger0_norm// addrC -subr_gt0 addrK.
Qed .
Lemma derivable_cos x : derivable cos x 1 .
Proof . by apply : ex_derive; apply : is_derive_cos. Qed .
Lemma continuous_cos : continuous cos.
Proof .
by move => x; exact /differentiable_continuous/derivable1_diffP/derivable_cos.
Qed .
Lemma cos2Dsin2 x : (cos x) ^+ 2 + (sin x) ^+ 2 = 1 .
Proof .
set v := LHS; pattern x in v; move : @v; set f := (X in let _ := X x in _) => /=.
apply : (@eq_trans _ _ (f 0 )); last by rewrite /f sin0 cos0 expr1n expr0n addr0.
apply : is_derive_0_is_cst => {}x.
apply : trigger_derive; rewrite /GRing.scale /=.
by rewrite mulrN ![sin x * _]mulrC -opprD addrC subrr.
Qed .
Lemma cos_max x : `| cos x | <= 1 .
Proof .
rewrite -(expr_le1 (_ : 0 < 2 )%nat) // -normrX ger0_norm ?exprn_even_ge0 //.
by rewrite -(cos2Dsin2 x) ler_addl ?sqr_ge0 .
Qed .
Lemma cos_geN1 x : -1 <= cos x.
Proof . by rewrite ler_oppl; have /ler_normlP[] := cos_max x. Qed .
Lemma cos_le1 x : cos x <= 1 .
Proof . by have /ler_normlP[] := cos_max x. Qed .
Lemma sin_max x : `| sin x | <= 1 .
Proof .
rewrite -(expr_le1 (_ : 0 < 2 )%nat) // -normrX ger0_norm ?exprn_even_ge0 //.
by rewrite -(cos2Dsin2 x) ler_addr ?sqr_ge0 .
Qed .
Lemma sin_geN1 x : -1 <= sin x.
Proof . by rewrite ler_oppl; have /ler_normlP[] := sin_max x. Qed .
Lemma sin_le1 x : sin x <= 1 .
Proof . by have /ler_normlP[] := sin_max x. Qed .
Fact sinD_cosD x y :
(sin (x + y) - (sin x * cos y + cos x * sin y)) ^+ 2 +
(cos (x + y) - (cos x * cos y - sin x * sin y)) ^+ 2 = 0 .
Proof .
set v := LHS; pattern x in v; move : @v; set f := (X in let _ := X x in _) => /=.
apply : (@eq_trans _ _ (f 0 )); last first .
by rewrite /f cos0 sin0 !(mul1r, mul0r, add0r, subr0, subrr, expr0n).
apply : is_derive_0_is_cst => {}x.
by apply : trigger_derive; rewrite /GRing.scale /=; nsatz .
Qed .
Lemma sinD x y : sin (x + y) = sin x * cos y + cos x * sin y.
Proof .
have /eqP := sinD_cosD x y.
rewrite paddr_eq0 => [/andP[]||]; try exact : sqr_ge0.
by rewrite sqrf_eq0 subr_eq0 => /eqP.
Qed .
Lemma cosD x y : cos (x + y) = cos x * cos y - sin x * sin y.
Proof .
have /eqP := sinD_cosD x y.
rewrite paddr_eq0 => [/andP[_]||]; try exact : sqr_ge0.
by rewrite sqrf_eq0 subr_eq0 => /eqP.
Qed .
Lemma sin2cos2 x : sin x ^+ 2 = 1 - cos x ^+ 2 .
Proof . by move /eqP: (cos2Dsin2 x); rewrite eq_sym addrC -subr_eq => /eqP. Qed .
Lemma cos2sin2 x : cos x ^+ 2 = 1 - sin x ^+ 2 .
Proof . by move /eqP: (cos2Dsin2 x); rewrite eq_sym -subr_eq => /eqP. Qed .
Lemma sin_mulr2n x : sin (x *+ 2 ) = (cos x * sin x) *+ 2 .
Proof . by rewrite mulr2n sinD mulrC -mulr2n. Qed .
Lemma cos_mulr2n x : cos (x *+ 2 ) = cos x ^+2 *+ 2 - 1 .
Proof . by rewrite mulr2n cosD -!expr2 sin2cos2 opprB addrA mulr2n. Qed .
Fact sinN_cosN x :
(sin (- x) + sin x) ^+ 2 + (cos (- x) - cos x) ^+ 2 = 0 .
Proof .
set v := LHS; pattern x in v; move : @v; set f := (X in let _ := X x in _) => /=.
apply : (@eq_trans _ _ (f 0 )); last first .
by rewrite /f oppr0 cos0 sin0 !(addr0, subrr, expr0n).
apply : is_derive_0_is_cst => {}x.
by apply : trigger_derive; rewrite /GRing.scale /=; nsatz .
Qed .
Lemma sinN x : sin (- x) = - sin x.
Proof .
have /eqP := sinN_cosN x.
rewrite paddr_eq0 => [/andP[]||]; try exact : sqr_ge0.
by rewrite sqrf_eq0 addr_eq0 => /eqP.
Qed .
Lemma cosN x : cos (- x) = cos x.
Proof .
have /eqP := sinN_cosN x.
rewrite paddr_eq0 => [/andP[_]||]; try exact : sqr_ge0.
by rewrite sqrf_eq0 subr_eq0 => /eqP.
Qed .
Lemma sin_sg x y : sin (Num.sg x * y) = Num.sg x * sin y.
Proof . by case : sgrP; rewrite ?mul1r ?mulN1r ?sinN // !mul0r sin0. Qed .
Lemma cos_sg x y : x != 0 -> cos (Num.sg x * y) = cos y.
Proof . by case : sgrP; rewrite ?mul1r ?mulN1r ?cosN . Qed .
Lemma cosB x y : cos (x - y) = cos x * cos y + sin x * sin y.
Proof . by rewrite cosD cosN sinN mulrN opprK. Qed .
Lemma sinB x y : sin (x - y) = sin x * cos y - cos x * sin y.
Proof . by rewrite sinD cosN sinN mulrN. Qed .
Lemma norm_cos_eq1 x : (`|cos x| == 1 ) = (sin x == 0 ).
Proof .
rewrite -sqrf_eq0 -sqrp_eq1 // -normrX ger0_norm ?exprn_even_ge0 //.
by rewrite [X in _ = (X == _)]sin2cos2 subr_eq0 eq_sym.
Qed .
Lemma norm_sin_eq1 x : (`|sin x| == 1 ) = (cos x == 0 ).
Proof .
rewrite -sqrf_eq0 -sqrp_eq1 // -normrX ger0_norm ?exprn_even_ge0 //.
by rewrite [X in _ = (X == _)]cos2sin2 subr_eq0 eq_sym.
Qed .
Lemma cos1sin0 x : `|cos x| = 1 -> sin x = 0 .
Proof . by move /eqP; rewrite norm_cos_eq1 => /eqP. Qed .
Lemma sin1cos0 x : `|sin x| = 1 -> cos x = 0 .
Proof . by move /eqP; rewrite norm_sin_eq1 => /eqP. Qed .
Lemma sin0cos1 x : sin x = 0 -> `|cos x| = 1 .
Proof . by move /eqP; rewrite -norm_cos_eq1 => /eqP. Qed .
Lemma cos_norm x : cos `|x| = cos x.
Proof . by case : (ler0P x); rewrite ?cosN . Qed .
End CosSin .
Arguments sin {R}.
Arguments cos {R}.
Section Pi .
Variable R : realType.
Implicit Types (x y : R) (n k : nat).
Definition pi : R := get [set x | 0 <= x <= 2 /\ cos x = 0 ] *+ 2 .
Lemma pihalfE : pi / 2 = get [set x | 0 <= x <= 2 /\ cos x = 0 ].
Proof . by rewrite /pi -(mulr_natr (get _)) -mulrA divff ?mulr1 . Qed .
Lemma cos2_lt0 : cos 2 < 0 :> R.
Proof .
rewrite -(opprK (cos _)) oppr_lt0; have /cvgN h := @cvg_cos_coeff' R 2 .
rewrite -(cvg_lim (@Rhausdorff R) h).
apply : (@lt_trans _ _ (\sum_(0 <= i < 3 ) - cos_coeff' 2 i)).
do 3 rewrite big_nat_recl//; rewrite big_nil addr0 3 !cos_coeff'E double0.
rewrite cos_coeff_2_0 cos_coeff_2_2 -muln2 cos_coeff_2_4 addrA -(opprD 1 ).
rewrite opprB -(@natrB _ 2 1 )// subn1/= -[in X in X - _](@divff _ 3 %:R)//.
by rewrite -mulrBl divr_gt0// -natrB// -[(_ - _)%N]/_.+1 .
rewrite -seriesN lt_sum_lim_series //.
by move /cvgP in h; by rewrite seriesN.
move => d.
rewrite /cos_coeff' 2 !exprzD_nat (exprSz _ d.*2 ) -[in (-1 ) ^ d.*2 ](muln2 d).
rewrite -(exprnP _ (d * 2 )) (exprM (-1 )) sqrr_sign 2 !mulr1 -exprSzr.
rewrite (_ : 4 = 2 * 2 )%N // -(exprnP _ (2 * 2 )) (exprM (-1 )) sqrr_sign.
rewrite mul1r [(-1 ) ^ 3 ](_ : _ = -1 ) ?mulN1r ?mulNr ?opprK ; last first .
by rewrite -exprnP 2 !exprS expr1 mulrN1 opprK mulr1.
rewrite subr_gt0.
rewrite addnS doubleS -[X in 2 ^+ X]addn2 exprD -mulrA ltr_pmul2l//.
rewrite factS factS 2 !natrM mulrA invfM !mulrA.
rewrite ltr_pdivr_mulr ?ltr0n ?fact_gt0 // mulVf ?pnatr_eq0 ?gtn_eqF ?fact_gt0 //.
rewrite ltr_pdivr_mulr ?mul1r //.
by rewrite expr2 -!natrM ltr_nat !mulSn !add2n mul0n !addnS.
Qed .
Lemma sin2_gt0 x : 0 < x < 2 -> 0 < sin x.
Proof .
move => /andP[x_gt0 x_lt2].
have sinx := @cvg_sin_coeff' _ x.
rewrite -(cvg_lim (@Rhausdorff R) sinx).
rewrite [ltLHS](_ : 0 = \sum_(0 <= i < 0 ) sin_coeff' x i :> R); last first .
by rewrite big_nil.
rewrite lt_sum_lim_series //; first by move /cvgP in sinx.
move => d.
rewrite /sin_coeff' 2 !exprzD_nat (exprSz _ d.*2 ) -[in (-1 ) ^ d.*2 ](muln2 d).
rewrite -(exprnP _ (d * 2 )) (exprM (-1 )) sqrr_sign 2 !mulr1 -exprSzr.
rewrite !add0n!mul1r mulN1r -[d.*2 .+1 ]addn1 doubleD -addSn exprD.
rewrite -(ffact_fact (leq_addl _ _)) addnK.
rewrite mulNr -!mulrA -mulrBr mulr_gt0 ?exprn_gt0 //.
set u := _.+1 .
rewrite natrM invfM.
rewrite -[X in _ < X - _]mul1r !mulrA -mulrBl divr_gt0 //; last first .
by rewrite (ltr_nat _ 0 ) fact_gt0.
rewrite subr_gt0.
set v := _ ^_ _; rewrite -[ltRHS](divff (_ : v%:R != 0 )); last first .
by rewrite lt0r_neq0 // (ltr_nat _ 0 ) ffact_gt0 leq_addl.
rewrite ltr_pmul2r; last by rewrite invr_gt0 (ltr_nat _ 0 ) ffact_gt0 leq_addl.
rewrite {}/v !addnS addn0 !ffactnS ffactn0 muln1 /= natrM.
by rewrite (ltr_pmul (ltW _ ) (ltW _)) // (lt_le_trans x_lt2) // ler_nat.
Qed .
Lemma cos1_gt0 : cos 1 > 0 :> R.
Proof .
have h := @cvg_cos_coeff' R 1 ; rewrite -(cvg_lim (@Rhausdorff R) h).
apply : (@lt_trans _ _ (\sum_(0 <= i < 2 ) cos_coeff' 1 i)).
rewrite big_nat_recr//= big_nat_recr//= big_nil add0r.
rewrite /cos_coeff' expr0z expr1n fact0 !mul1r expr1n expr1z.
by rewrite !mulNr subr_gt0 mul1r div1r ltf_pinv ?posrE ?ltr0n // ltr_nat.
rewrite lt_sum_lim_series //; [by move /cvgP in h|move => d].
rewrite /cos_coeff' !(expr1n,mulr1).
rewrite -muln2 -mulSn muln2 -exprnP -signr_odd odd_double expr0.
rewrite -exprnP -signr_odd oddD/= muln2 odd_double/= expr1 add2n.
rewrite mulNr subr_gt0 2 !div1r ltf_pinv ?posrE ?ltr0n ?fact_gt0 //.
by rewrite ltr_nat ltn_pfact//ltn_double doubleS.
Qed .
Lemma cos_exists : exists2 pih : R, 1 <= pih <= 2 & cos pih = 0 .
Proof .
have /IVT[] : minr (cos 1 ) (cos 2 ) <= (0 : R) <= maxr (cos 1 ) (cos 2 ).
- by rewrite le_maxr (ltW cos1_gt0) le_minl (ltW cos2_lt0) orbC.
- by rewrite ler1n.
- by apply /continuous_subspaceT => ?; exact : continuous_cos.
by move => pih /itvP pihI chpi_eq0; exists pih ; rewrite ?pihI .
Qed .
Lemma cos_02_uniq x y :
0 <= x <= 2 -> cos x = 0 -> 0 <= y <= 2 -> cos y = 0 -> x = y.
Proof .
wlog xLy : x y / x <= y => [H xB cx0 yB cy0|].
by case : (lerP x y) => [/H //| /ltW /H H1]; [exact |exact /esym/H1].
move => /andP[x_ge0 x_le2] cx0 /andP[y_ge0 y_le2] cy0.
case : (x =P y) => // /eqP xDy.
have xLLs : x < y by rewrite le_eqVlt (negPf xDy) in xLy.
have /(Rolle xLLs)[x1 _|x1|x1 x1I [_ x1D]] : cos x = cos y by rewrite cy0.
- exact : derivable_cos.
- by apply /continuous_subspaceT => ?; exact : continuous_cos.
- have [_ /esym/eqP] := is_derive_cos x1; rewrite x1D oppr_eq0 => /eqP Hs.
suff : 0 < sin x1 by rewrite Hs ltxx.
apply /sin2_gt0/andP; split .
+ by rewrite (le_lt_trans x_ge0)// (itvP x1I).
+ by rewrite (lt_le_trans _ y_le2)// (itvP x1I).
Qed .
Lemma pihalf_02_cos_pihalf : 0 <= pi / 2 <= 2 /\ cos (pi / 2 ) = 0 .
Proof .
have [x /andP[x1 x2] cs0] := cos_exists; rewrite pihalfE.
case : xgetP => [_->[]//|/(_ x)/=].
by rewrite cs0 (le_trans _ x1)// x2 => /not_andP[].
Qed .
#[deprecated(note="Use pihalf_ge1 and pihalf_lt2 instead" )]
Lemma pihalf_02 : 0 < pi / 2 < 2 .
Proof .
have [pih02 cpih] := pihalf_02_cos_pihalf.
rewrite 2 !lt_neqAle andbCA -andbA pih02 andbT; apply /andP; split .
by apply /eqP => pih2; have := cos2_lt0; rewrite -pih2 cpih ltxx.
apply /eqP => pih0; have := @cos0 R.
by rewrite pih0 cpih; apply /eqP; rewrite eq_sym oner_eq0.
Qed .
Let pihalf_12 : 1 <= pi / 2 < 2 .
Proof .
have [/andP[pih0 pih2] cpih] := pihalf_02_cos_pihalf.
rewrite lt_neqAle andbA andbAC pih2 andbT; apply /andP; split ; last first .
by apply /eqP => hpi2; have := cos2_lt0; rewrite -hpi2 cpih ltxx.
rewrite leNgt; apply /negP => hpi1; have [x /andP[x1 x2] cs0] := cos_exists.
have := @cos_02_uniq (pi / 2 ) x.
rewrite pih0 pih2 cpih (le_trans _ x1)// x2 cs0 => /(_ erefl erefl erefl erefl).
by move => pih; move : hpi1; rewrite pih => /lt_le_trans/(_ x1); rewrite ltxx.
Qed .
Lemma pihalf_ge1 : 1 <= pi / 2 .
Proof . by have /andP[] := pihalf_12. Qed .
Lemma pihalf_lt2 : pi / 2 < 2 .
Proof . by have /andP[] := pihalf_12. Qed .
Lemma pi_ge2 : 2 <= pi.
Proof . by have := pihalf_ge1; rewrite ler_pdivl_mulr// mul1r. Qed .
Lemma pi_gt0 : 0 < pi. Proof . by rewrite (lt_le_trans _ pi_ge2). Qed .
Lemma pi_ge0 : 0 <= pi. Proof . exact : (ltW pi_gt0). Qed .
Lemma sin_gt0_pihalf x : 0 < x < pi / 2 -> 0 < sin x.
Proof .
move => /andP[x_gt0 xLpi]; apply : sin2_gt0; rewrite x_gt0 /=.
by apply : lt_trans xLpi _; exact : pihalf_lt2.
Qed .
Lemma cos_gt0_pihalf x : -(pi / 2 ) < x < pi / 2 -> 0 < cos x.
Proof .
wlog : x / 0 <= x => [Hw|x_ge0].
case : (leP 0 x) => [/Hw//| x_lt_0].
rewrite -{-1 }[x]opprK ltr_oppl andbC [-- _ < _]ltr_oppl cosN.
by apply : Hw => //; rewrite oppr_cp0 ltW.
move => /andP[x_gt0 xLpi2]; case : (ler0P (cos x)) => // cx_le0.
have /IVT[]// : minr (cos 0 ) (cos x) <= 0 <= maxr (cos 0 ) (cos x).
by rewrite cos0 /minr /maxr !ifN ?cx_le0 //= -leNgt (le_trans cx_le0).
- by apply /continuous_subspaceT => ?; exact : continuous_cos.
move => x1 /itvP xx1 cx1_eq0.
suff x1E : x1 = pi/2 .
have : x1 < pi / 2 by apply : le_lt_trans xLpi2; rewrite xx1.
by rewrite x1E ltxx.
apply : cos_02_uniq=> //; last by case pihalf_02_cos_pihalf => _ ->.
by rewrite xx1 ltW // (lt_trans _ pihalf_lt2) // (le_lt_trans _ xLpi2) // xx1.
by rewrite divr_ge0 ?(ltW pihalf_lt2)// pi_ge0.
Qed .
Lemma cos_pihalf : cos (pi / 2 ) = 0 . Proof . exact : pihalf_02_cos_pihalf.2 . Qed .
Lemma sin_pihalf : sin (pi / 2 ) = 1 .
Proof .
have := cos2Dsin2 (pi / 2 ); rewrite cos_pihalf expr0n add0r.
rewrite -[in X in _ = X -> _](expr1n _ 2 %N) => /eqP; rewrite -subr_eq0 subr_sqr.
rewrite mulf_eq0=> /orP[|]; first by rewrite subr_eq0=> /eqP.
rewrite addr_eq0 => /eqP spi21; have /sin2_gt0: 0 < pi / 2 < 2 .
by rewrite pihalf_lt2 andbT (lt_le_trans _ pihalf_ge1).
by rewrite spi21 ltr0N1.
Qed .
Lemma cos_ge0_pihalf x : -(pi / 2 ) <= x <= pi / 2 -> 0 <= cos x.
Proof .
rewrite le_eqVlt; case : (_ =P x) => /= [<-|_].
by rewrite cosN cos_pihalf.
rewrite le_eqVlt; case : (x =P _) => /= [->|_ H]; first by rewrite cos_pihalf.
by rewrite ltW //; apply : cos_gt0_pihalf.
Qed .
Lemma cospi : cos pi = - 1 .
Proof .
by rewrite /pi mulr2n cosD -pihalfE sin_pihalf mulr1 cos_pihalf mulr0 add0r.
Qed .
Lemma sinpi : sin pi = 0 .
Proof .
have := sinD (pi / 2 ) (pi / 2 ); rewrite cos_pihalf mulr0 mul0r.
by rewrite -mulrDl -mulr2n -mulr_natr -mulrA divff// mulr1 addr0.
Qed .
Lemma cos2pi : cos (pi *+ 2 ) = 1 .
Proof . by rewrite mulr2n cosD cospi sinpi !mulrN1 mulr0 subr0 opprK. Qed .
Lemma sin2pi : sin (pi *+ 2 ) = 0 .
Proof . by rewrite mulr2n sinD sinpi cospi !mulrN1 mulr0 oppr0 addr0. Qed .
Lemma sinDpi : alternating sin pi.
Proof . by move => a; rewrite sinD cospi mulrN1 sinpi mulr0 addr0. Qed .
Lemma cosDpi : alternating cos pi.
Proof . by move => a; rewrite cosD cospi mulrN1 sinpi mulr0 subr0. Qed .
Lemma sinD2pi : periodic sin (pi *+ 2 ).
Proof . by move => a; rewrite sinD cos2pi sin2pi mulr0 mulr1 addr0. Qed .
Lemma cosD2pi : periodic cos (pi *+ 2 ).
Proof . by move => a; rewrite cosD cos2pi mulr1 sin2pi mulr0 subr0. Qed .
Lemma cosDpihalf a : cos (a + pi / 2 ) = - sin a.
Proof . by rewrite cosD cos_pihalf mulr0 add0r sin_pihalf mulr1. Qed .
Lemma cosBpihalf a : cos (a - pi / 2 ) = sin a.
Proof . by rewrite cosB cos_pihalf mulr0 add0r sin_pihalf mulr1. Qed .
Lemma sinDpihalf a : sin (a + pi / 2 ) = cos a.
Proof . by rewrite sinD cos_pihalf mulr0 add0r sin_pihalf mulr1. Qed .
Lemma sinBpihalf a : sin (a - pi / 2 ) = - cos a.
Proof . by rewrite sinB cos_pihalf mulr0 add0r sin_pihalf mulr1. Qed .
Lemma sin_ge0_pi x : 0 <= x <= pi -> 0 <= sin x.
Proof .
move => xI; rewrite -cosBpihalf cos_ge0_pihalf //.
by rewrite ler_subr_addl subrr ler_sub_addr -mulr2n -[_ *+ 2 ]mulr_natr divfK.
Qed .
Lemma sin_gt0_pi x : 0 < x < pi -> 0 < sin x.
Proof .
move => xI; rewrite -cosBpihalf cos_gt0_pihalf //.
by rewrite ltr_subr_addl subrr ltr_sub_addr -mulr2n -[_ *+ 2 ]mulr_natr divfK.
Qed .
Lemma ltr_cos : {in `[0 , pi] &, {mono cos : x y /~ y < x}}.
Proof .
move => x y; rewrite !in_itv/= le_eqVlt; case : eqP => [<- _|_] /=.
rewrite cos0 le_eqVlt; case : eqP => /= [<- _|_ /andP[y_gt0 gLpi]].
by rewrite cos0 !ltxx.
rewrite y_gt0; apply /idP.
suff : cos y != 1 by case : ltrgtP (cos_le1 y).
rewrite -cos0 eq_sym; apply /eqP => /Rolle [||x1|x1 /itvP x1I [_ x1D]] //.
by apply /continuous_subspaceT => ?; exact : continuous_cos.
case : (is_derive_cos x1) => _ /eqP; rewrite x1D eq_sym oppr_eq0 => /eqP s_eq0.
suff : 0 < sin x1 by rewrite s_eq0 ltxx.
by apply : sin_gt0_pi; rewrite x1I /= (lt_le_trans (_ : _ < y)) ?x1I // yI.
rewrite le_eqVlt; case : eqP => [-> _ /andP[y_ge0]|/= _ /andP[x_gt0 x_ltpi]] /=.
rewrite cospi le_eqVlt; case : eqP => /= [-> _|/eqP yDpi y_ltpi].
by rewrite cospi ltxx.
by rewrite ltNge cos_geN1 ltNge ltW.
rewrite le_eqVlt; case : eqP => [<- _|_] /=.
rewrite cos0 [_ < 0 ]ltNge ltW //=.
by apply /idP/negP; rewrite -leNgt cos_le1.
rewrite le_eqVlt; case : eqP => /= [-> _ | _ /andP[y_gt0 y_ltpi]].
rewrite cospi x_ltpi; apply /idP.
suff : cos x != -1 by case : ltrgtP (cos_geN1 x).
rewrite -cospi; apply /eqP => /Rolle [||x1|x1 /itvP x1I [_ x1D]] //.
by apply /continuous_subspaceT => ?; exact : continuous_cos.
case : (is_derive_cos x1) => _ /eqP; rewrite x1D eq_sym oppr_eq0 => /eqP s_eq0.
suff : 0 < sin x1 by rewrite s_eq0 ltxx.
by apply : sin_gt0_pi; rewrite x1I /= (lt_le_trans (_ : _ < x)) ?x1I .
wlog xLy : x y x_gt0 x_ltpi y_gt0 y_ltpi / x <= y => [H | ].
case : (lerP x y) => [/H //->//|yLx].
by rewrite !ltNge ltW ?(ltW yLx) // H // ltW.
case : (x =P y) => [->| /eqP xDy]; first by rewrite ltxx.
have xLLs : x < y by rewrite le_eqVlt (negPf xDy) in xLy.
rewrite xLLs -subr_gt0 -opprB; rewrite -subr_gt0 in xLLs; apply /idP.
have [x1|z /itvP zI ->] := @MVT_segment _ cos (- sin) _ _ xLy.
by apply /continuous_subspaceT => ?; exact : continuous_cos.
rewrite -mulNr opprK mulr_gt0 //; apply : sin_gt0_pi.
by rewrite (lt_le_trans x_gt0) ?zI //= (le_lt_trans _ y_ltpi) ?zI .
Qed .
Lemma ltr_sin : {in `[ (- (pi/2 )), pi/2 ] &, {mono sin : x y / x < y}}.
Proof .
move => x y /itvP xpi /itvP ypi; rewrite -[sin x]opprK ltr_oppl.
rewrite -!cosDpihalf -[x < y](ltr_add2r (pi /2 )) ltr_cos// !in_itv/=.
- by rewrite -ler_subl_addr sub0r xpi/= [leRHS]splitr ler_add2r xpi.
- by rewrite -ler_subl_addr sub0r ypi/= [leRHS]splitr ler_add2r ypi.
Qed .
Lemma cos_inj : {in `[0 ,pi] &, injective (@cos R)}.
Proof .
move => x y x0pi y0pi xy; apply /eqP; rewrite eq_le; apply /andP; split .
- by have := ltr_cos y0pi x0pi; rewrite xy ltxx => /esym/negbT; rewrite -leNgt.
- by have := ltr_cos x0pi y0pi; rewrite xy ltxx => /esym/negbT; rewrite -leNgt.
Qed .
Lemma sin_inj : {in `[(- (pi/2 )), (pi/2 )] &, injective sin}.
Proof .
move => x y /itvP xpi /itvP ypi sinE; have : - sin x = - sin y by rewrite sinE.
rewrite -!cosDpihalf => /cos_inj h; apply /(addIr (pi/2 ))/h; rewrite !in_itv/=.
- by rewrite -ler_subl_addr sub0r xpi/= [leRHS]splitr ler_add2r xpi.
- by rewrite -ler_subl_addr sub0r ypi/= [leRHS]splitr ler_add2r ypi.
Qed .
End Pi .
Arguments pi {R}.
Section Tan .
Variable R : realType.
Definition tan (x : R) := sin x / cos x.
Lemma tan0 : tan 0 = 0 :> R.
Proof . by rewrite /tan sin0 cos0 mul0r. Qed .
Lemma tanpi : tan pi = 0 .
Proof . by rewrite /tan sinpi mul0r. Qed .
Lemma tanN x : tan (- x) = - tan x.
Proof . by rewrite /tan sinN cosN mulNr. Qed .
Lemma tanD x y : cos x != 0 -> cos y != 0 ->
tan (x + y) = (tan x + tan y) / (1 - tan x * tan y).
Proof .
move => cxNZ cyNZ.
rewrite /tan sinD cosD !addf_div // [sin y * cos x]mulrC -!mulrA -invfM.
congr (_ / _).
rewrite mulrBr mulr1 !mulrA.
rewrite -[_ * _ * sin x]mulrA [cos x * (_ * _)]mulrC mulfK //.
by rewrite -[_ * _ * sin y]mulrA [cos y * (_ * _)]mulrC mulfK.
Qed .
Lemma tan_mulr2n x :
cos x != 0 -> tan (x *+ 2 ) = tan x *+ 2 / (1 - tan x ^+ 2 ).
Proof .
move => cxNZ.
rewrite /tan cos_mulr2n sin_mulr2n.
rewrite !mulr2n exprMn exprVn -[in RHS](divff (_ : 1 != 0 )) //.
rewrite -mulNr !addf_div ?sqrf_eq0 //.
rewrite mul1r mulr1 -!mulrA -invfM -expr2; congr (_ / _).
by rewrite [cos x * _]mulrC.
rewrite mulrCA mulrA mulfK ?sqrf_eq0 // [X in _ = _ - X]sin2cos2.
by rewrite opprB addrA.
Qed .
Lemma cos2_tan2 x : cos x != 0 -> (cos x) ^- 2 = 1 + (tan x) ^+ 2 .
Proof .
move => cosx.
rewrite /tan exprMn [X in _ = 1 + X * _]sin2cos2 mulrBl -exprMn divff //.
by rewrite expr1n addrCA subrr addr0 mul1r exprVn.
Qed .
Lemma tan_pihalf : tan (pi / 2 ) = 0 .
Proof . by rewrite /tan cos_pihalf invr0 mulr0. Qed .
Lemma tan_piquarter : tan (pi / 4 %:R) = 1 .
Proof .
rewrite /tan -cosBpihalf (splitr (pi / 2 )) opprD addrA -mulrA -invfM -natrM.
rewrite subrr sub0r cosN divff// gt_eqF// cos_gt0_pihalf//.
rewrite ltr_pmul2l ?pi_gt0 // ltf_pinv ?qualifE // ltr_nat andbT.
by rewrite (@lt_trans _ _ 0 )// ?oppr_lt0 ?divr_gt0 ?pi_gt0 .
Qed .
Lemma tanDpi x : tan (x + pi) = tan x.
Proof . by rewrite /tan cosDpi sinDpi mulNr invrN mulrN opprK. Qed .
Lemma continuous_tan x : cos x != 0 -> {for x, continuous tan}.
Proof .
move => cxNZ.
apply : continuousM; first exact : continuous_sin.
exact /(continuousV cxNZ)/continuous_cos.
Qed .
Lemma is_derive_tan x :
cos x != 0 -> is_derive x 1 tan ((cos x)^-2 ).
Proof .
move => cxNZ; apply : trigger_derive.
rewrite /= ![_ *: - _]mulrN mulNr mulrN opprK [_^-1 *: _]mulVf //.
rewrite mulrCA -expr2 [X in _ * X + _ = _]sin2cos2.
by rewrite mulrBr mulr1 mulVf ?sqrf_eq0 // subrK.
Qed .
Lemma derivable_tan x : cos x != 0 -> derivable tan x 1 .
Proof . by move => /is_derive_tan[]. Qed .
Lemma ltr_tan : {in `](- (pi/2 )), (pi/2 )[ &, {mono tan : x y / x < y}}.
Proof .
move => x y; wlog xLy : x y / x <= y => [H xB yB|/itvP xB /itvP yB].
case : (lerP x y) => [/H //->//|yLx].
by rewrite !ltNge ltW ?(ltW yLx) // H // ltW.
case : (x =P y) => [->| /eqP xDy]; first by rewrite ltxx.
have xLLs : x < y by rewrite le_eqVlt (negPf xDy) in xLy.
rewrite -subr_gt0 xLLs; rewrite -subr_gt0 in xLLs; apply /idP.
have [x1 /itvP x1I|z |] := @MVT_segment _ tan (fun x => (cos x) ^-2 ) _ _ xLy.
- apply : is_derive_tan.
rewrite gt_eqF // cos_gt0_pihalf // (@lt_le_trans _ _ x) ?x1I ?xB //=.
by rewrite (@le_lt_trans _ _ y) ?x1I ?yB .
- apply /continuous_in_subspaceT => ? -/[!(@mem_setE R)] /itvP inI.
apply : continuous_tan; rewrite gt_eqF// cos_gt0_pihalf//.
by rewrite (@lt_le_trans _ _ x) ?xB ?inI // (@le_lt_trans _ _ y) ?yB ?inI .
- move => x1 /itvP x1I ->.
rewrite mulr_gt0 // invr_gt0 // exprn_gte0 // cos_gt0_pihalf //.
by rewrite (@lt_le_trans _ _ x) ?x1I ?xB //= (@le_lt_trans _ _ y) ?x1I ?yB .
Qed .
Lemma tan_inj : {in `](- (pi/2 )), (pi/2 )[ &, injective tan}.
Proof .
move => x y xB yB tanE.
by case : (ltrgtP x y); rewrite // -ltr_tan ?tanE ?ltxx .
Qed .
End Tan .
Arguments tan {R}.
#[global ] Hint Extern 0 (is_derive _ _ tan _) =>
(eapply is_derive_tan; first by []) : typeclass_instances.
Section Acos .
Variable R : realType.
Definition acos (x : R) : R := get [set y | 0 <= y <= pi /\ cos y = x].
Lemma acos_def x :
-1 <= x <= 1 -> 0 <= acos x <= pi /\ cos (acos x) = x.
Proof .
move => xB; rewrite /acos; case : xgetP => //= He.
pose f y := cos y - x.
have /(IVT (@pi_ge0 _))[] // : minr (f 0 ) (f pi) <= 0 <= maxr (f 0 ) (f pi).
rewrite /f cos0 cospi /minr /maxr ltr_add2r -subr_lt0 opprK (_ : 1 + 1 = 2 )//.
by rewrite ltrn0 subr_le0 subr_ge0.
- move => y y0pi.
by apply : continuousB; apply /continuous_in_subspaceT => ? ?;
[exact : continuous_cos|exact : cst_continuous].
- rewrite /f => x1 /itvP x1I /eqP; rewrite subr_eq0 => /eqP cosx1E.
by case : (He x1); rewrite !x1I.
Qed .
Lemma acos_ge0 x : -1 <= x <= 1 -> 0 <= acos x.
Proof . by move => /acos_def[/andP[]]. Qed .
Lemma acos_lepi x : -1 <= x <= 1 -> acos x <= pi.
Proof . by move => /acos_def[/andP[]]. Qed .
Lemma acosK : {in `[(-1 ),1 ], cancel acos cos}.
Proof . by move => x; rewrite in_itv/==> /acos_def[/andP[]]. Qed .
Lemma acos_gt0 x : -1 <= x < 1 -> 0 < acos x.
Proof .
move => /andP[x_geN1 x_lt1]; move : (x_lt1).
have : 0 <= acos x by rewrite acos_ge0 // x_geN1 ltW.
have : cos (acos x) = x by rewrite acosK// in_itv/= x_geN1/= ltW.
by case : ltrgt0P => // ->; rewrite cos0 => ->; rewrite ltxx.
Qed .
Lemma acos_ltpi x : -1 < x <= 1 -> acos x < pi.
Proof .
move => /andP[x_gtN1 x_le1]; move : (x_gtN1).
have : acos x <= pi by rewrite acos_lepi // x_le1 ltW.
have : cos (acos x) = x by rewrite acosK// in_itv/= x_le1 ltW.
by case : (ltrgtP (acos x) pi) => // ->; rewrite cospi => ->; rewrite ltxx.
Qed .
Lemma cosK : {in `[0 , pi], cancel cos acos}.
Proof .
move => x xB; apply : cos_inj => //; rewrite ?acosK //; last first .
by move : xB; rewrite !in_itv/= => /andP[? ?];rewrite cos_geN1 cos_le1.
move : xB; rewrite !in_itv/= => /andP[? ?].
by rewrite acos_ge0 ?acos_lepi ?cos_geN1 ?cos_le1 .
Qed .
Lemma acos1 : acos (1 : R) = 0 .
Proof .
by have := @cosK 0 ; rewrite cos0 => -> //; rewrite in_itv //= lexx pi_ge0.
Qed .
Lemma acos0 : acos (0 : R) = pi / 2 %:R.
Proof .
have := @cosK (pi / 2 %:R).
rewrite cos_pihalf => -> //; rewrite in_itv//= divr_ge0 ?ler0n ?pi_ge0 //=.
by rewrite ler_pdivr_mulr ?ltr0n // ler_pemulr ?pi_ge0 // ler1n.
Qed .
Lemma acosN a : -1 <= a <= 1 -> acos (- a) = pi - acos a.
Proof .
move => a1; have ? : -1 <= - a <= 1 by rewrite ler_oppl opprK ler_oppl andbC.
apply : cos_inj; first by rewrite in_itv/= acos_ge0//= acos_lepi.
- by rewrite in_itv/= subr_ge0 acos_lepi//= ler_subl_addl ler_addr acos_ge0.
- by rewrite addrC cosDpi cosN !acosK.
Qed .
Lemma acosN1 : acos (- 1 ) = (pi : R).
Proof . by rewrite acosN ?acos1 ?subr0 ?lexx // -subr_ge0 opprK addr_ge0. Qed .
Lemma cosKN a : - pi <= a <= 0 -> acos (cos a) = - a.
Proof .
by move => pia0; rewrite -(cosN a) cosK// in_itv/= ler_oppr oppr0 ler_oppl andbC.
Qed .
Lemma sin_acos x : -1 <= x <= 1 -> sin (acos x) = Num.sqrt (1 - x^+2 ).
Proof .
move => xB.
rewrite -[LHS]ger0_norm; last by rewrite sin_ge0_pi // acos_ge0 ?acos_lepi .
by rewrite -sqrtr_sqr sin2cos2 acosK.
Qed .
Lemma continuous_acos x : -1 < x < 1 -> {for x, continuous acos}.
Proof .
move => /andP[x_gtN1 x_lt1]; rewrite -[x]acosK; first last .
by have : -1 <= x <= 1 by rewrite !ltW //; case /andP: xB.
apply : nbhs_singleton (near_can_continuous _ _); last first .
by near=> z; apply : continuous_cos.
have /near_in_itv aI : acos x \in `]0 , pi[.
suff : 0 < acos x < pi by [].
by rewrite acos_gt0 ?ltW //= acos_ltpi // ltW ?andbT .
near=> z; apply : cosK.
suff /itvP zI : z \in `]0 , pi[ by have : 0 <= z <= pi by rewrite ltW ?zI .
by near: z.
Unshelve . all : by end_near. Qed .
Lemma is_derive1_acos (x : R) :
-1 < x < 1 -> is_derive x 1 acos (- (Num.sqrt (1 - x ^+ 2 ))^-1 ).
Proof .
move => /andP[x_gtN1 x_lt1]; rewrite -sin_acos ?ltW // -invrN.
rewrite -{1 }[x]acosK; last by have : -1 <= x <= 1 by rewrite ltW // ltW.
have /near_in_itv aI : acos x \in `]0 , pi[.
suff : 0 < acos x < pi by [].
by rewrite acos_gt0 ?ltW //= acos_ltpi // ltW ?andbT .
apply : (@is_derive_inverse R cos).
- near=> z; apply : cosK.
suff /itvP zI : z \in `]0 , pi[ by have : 0 <= z <= pi by rewrite ltW ?zI .
by near: z.
- by near=> z; apply : continuous_cos.
- rewrite oppr_eq0 sin_acos ?ltW // sqrtr_eq0 // -ltNge subr_gt0.
rewrite -real_normK ?qualifE ; last by case : ltrgt0P.
by rewrite exprn_cp1 // ltr_norml x_gtN1.
Unshelve . all : by end_near. Qed .
End Acos .
#[global ] Hint Extern 0 (is_derive _ 1 (@acos _) _) =>
(eapply is_derive1_acos; first by []) : typeclass_instances.
Section Asin .
Variable R : realType.
Definition asin (x : R) : R := get [set y | -(pi / 2 ) <= y <= pi / 2 /\ sin y = x].
Lemma asin_def x :
-1 <= x <= 1 -> -(pi / 2 ) <= asin x <= pi / 2 /\ sin (asin x) = x.
Proof .
move => xB; rewrite /asin; case : xgetP => //= He.
pose f y := sin y - x.
have /IVT[] // :
minr (f (-(pi/2 ))) (f (pi/2 )) <= 0 <= maxr (f (-(pi/2 ))) (f (pi/2 )).
rewrite /f sinN sin_pihalf /minr /maxr ltr_add2r -subr_gt0 opprK.
by rewrite (_ : 1 + 1 = 2 )// ltr0n/= subr_le0 subr_ge0.
- by rewrite -subr_ge0 opprK -splitr pi_ge0.
- by move => *; apply : continuousB; apply /continuous_in_subspaceT => ? ?;
[exact : continuous_sin| exact : cst_continuous].
- rewrite /f => x1 /itvP x1I /eqP; rewrite subr_eq0 => /eqP sinx1E.
by case : (He x1); rewrite !x1I.
Qed .
Lemma asin_geNpi2 x : -1 <= x <= 1 -> -(pi / 2 ) <= asin x.
Proof . by move => /asin_def[/andP[]]. Qed .
Lemma asin_lepi2 x : -1 <= x <= 1 -> asin x <= pi / 2 .
Proof . by move => /asin_def[/andP[]]. Qed .
Lemma asinK : {in `[(-1 ),1 ], cancel asin sin}.
Proof . by move => x; rewrite in_itv/= => /asin_def[/andP[]]. Qed .
Lemma asin_ltpi2 x : -1 <= x < 1 -> asin x < pi/2 .
Proof .
move => /andP[x_geN1 x_lt1]; move : (x_lt1).
have : asin x <= pi / 2 by rewrite asin_lepi2 // x_geN1 ltW.
have : sin (asin x) = x by rewrite asinK// in_itv/= x_geN1 ltW.
case : (ltrgtP _ ((pi / 2 ))) => // ->.
by rewrite sin_pihalf => <-; rewrite ltxx.
Qed .
Lemma asin_gtNpi2 x : -1 < x <= 1 -> - (pi / 2 ) < asin x.
Proof .
move => /andP[x_gtN1 x_le1]; move : (x_gtN1).
have : - (pi / 2 ) <= asin x by rewrite asin_geNpi2 // x_le1 ltW.
have : sin (asin x) = x by rewrite asinK// in_itv/= x_le1 ltW.
by case : (ltrgtP (asin x)) => //->; rewrite sinN sin_pihalf => <-; rewrite ltxx.
Qed .
Lemma sinK : {in `[(- (pi / 2 )), pi / 2 ], cancel sin asin}.
Proof .
move => x; rewrite !in_itv/= => xB ; apply : sin_inj => //; last first .
by rewrite asinK// in_itv/= sin_geN1 sin_le1.
by rewrite in_itv/= asin_geNpi2/= ?asin_lepi2 ?sin_geN1 ?sin_le1 .
Qed .
Lemma cos_asin x : -1 <= x <= 1 -> cos (asin x) = Num.sqrt (1 - x^+2 ).
Proof .
move => xB; rewrite -[LHS]ger0_norm; first by rewrite -sqrtr_sqr cos2sin2 asinK.
by apply : cos_ge0_pihalf; rewrite asin_lepi2 // asin_geNpi2.
Qed .
Lemma continuous_asin x : -1 < x < 1 -> {for x, continuous asin}.
Proof .
move => /andP[x_gtN1 x_lt1]; rewrite -[x]asinK; first last .
by have : -1 <= x <= 1 by rewrite !ltW //; case /andP: xB.
apply : nbhs_singleton (near_can_continuous _ _); last first .
by near=> z; apply : continuous_sin.
have /near_in_itv aI : asin x \in `](-(pi/2 )), (pi/2 )[.
suff : - (pi / 2 ) < asin x < pi / 2 by [].
by rewrite asin_gtNpi2 ?ltW ?andbT //= asin_ltpi2 // ltW.
near=> z; apply : sinK.
suff /itvP zI : z \in `](-(pi/2 )), (pi/2 )[.
by have : - (pi / 2 ) <= z <= pi / 2 by rewrite ltW ?zI .
by near: z.
Unshelve . all : by end_near. Qed .
Lemma is_derive1_asin (x : R) :
-1 < x < 1 -> is_derive x 1 asin ((Num.sqrt (1 - x ^+ 2 ))^-1 ).
Proof .
move => /andP[x_gtN1 x_lt1]; rewrite -cos_asin ?ltW //.
rewrite -{1 }[x]asinK; last by have : -1 <= x <= 1 by rewrite ltW // ltW.
have /near_in_itv aI : asin x \in `](-(pi/2 )), (pi/2 )[.
suff : -(pi/2 ) < asin x < pi/2 by [].
by rewrite asin_gtNpi2 ?ltW ?andbT //= asin_ltpi2 // ltW.
apply : (@is_derive_inverse R sin).
- near=> z; apply : sinK.
suff /itvP zI : z \in `](-(pi/2 )), (pi/2 )[.
by have : - (pi / 2 ) <= z <= pi / 2 by rewrite ltW ?zI .
by near: z.
- by near=> z; exact : continuous_sin.
- rewrite cos_asin ?ltW // sqrtr_eq0 // -ltNge subr_gt0.
rewrite -real_normK ?qualifE ; last by case : ltrgt0P.
by rewrite exprn_cp1 // ltr_norml x_gtN1.
Unshelve . all : by end_near. Qed .
End Asin .
#[global ] Hint Extern 0 (is_derive _ 1 (@asin _) _) =>
(eapply is_derive1_asin; first by []) : typeclass_instances.
Section Atan .
Variable R : realType.
Definition atan (x : R) : R :=
get [set y | -(pi / 2 ) < y < pi / 2 /\ tan y = x].
(* Did not see how to use ITV like in the other *)
Lemma atan_def x : -(pi / 2 ) < atan x < pi / 2 /\ tan (atan x) = x.
Proof .
rewrite /atan; case : xgetP => //= He.
pose x1 := Num.sqrt (1 + x^+ 2 ) ^-1 .
have ox2_gt0 : 0 < 1 + x^2 .
by apply : lt_le_trans (_ : 1 <= _); rewrite ?ler_addl ?sqr_ge0 .
have ox2_ge0 : 0 <= 1 + x^2 by rewrite ltW.
have x1B : -1 <= x1 <= 1 .
rewrite -ler_norml /x1 ger0_norm ?sqrtr_ge0 // -[leRHS]sqrtr1.
by rewrite ler_psqrt ?qualifE ?invr_gte0 //= invf_cp1 // ler_addl sqr_ge0.
case : (He (Num.sg x * acos x1)); split ; last first .
case : (x =P 0 ) => [->|/eqP xD0]; first by rewrite /tan sgr0 mul0r sin0 mul0r.
rewrite /tan sin_sg cos_sg // acosK ?sin_acos //.
rewrite /x1 sqr_sqrtr// ?invr_ge0 //.
rewrite -{1 }[_^-1 in X in X / _ = _]mul1r.
rewrite -{1 }[X in X - _](divff (_: 1 != 0 )) //.
rewrite -mulNr addf_div ?lt0r_neq0 //.
rewrite mul1r mulr1 [X in X - 1 ]addrC addrK // sqrtrM ?sqr_ge0 //.
rewrite sqrtrV // invrK // mulrA divfK //; last by rewrite sqrtr_eq0 -ltNge.
by rewrite sqrtr_sqr mulr_sg_norm.
rewrite -ltr_norml normrM.
have pi2 : 0 < pi / 2 :> R by rewrite divr_gt0 // pi_gt0.
case : (x =P 0 ) => [->|/eqP xD0]; first by rewrite sgr0 normr0 mul0r.
rewrite normr_sg xD0 mul1r ltr_norml.
rewrite (@lt_le_trans _ _ 0 ) ?acos_ge0 ?oppr_cp0 //=.
rewrite -ltr_cos ?in_itv /= ?acos_ge0 /= ?acos_lepi //; last first .
by rewrite divr_ge0 ?pi_ge0 //= ler_pdivr_mulr// ler_pmulr ?pi_gt0 // ler1n.
by rewrite cos_pihalf acosK // ?sqrtr_gt0 ?invr_gt0 .
Qed .
Lemma atan_gtNpi2 x : - (pi / 2 ) < atan x.
Proof . by case : (atan_def x) => [] /andP[]. Qed .
Lemma atan_ltpi2 x : atan x < pi / 2 .
Proof . by case : (atan_def x) => [] /andP[]. Qed .
Lemma atanK : cancel atan tan.
Proof . by move => x; case : (atan_def x). Qed .
Lemma atan0 : atan 0 = 0 :> R.
Proof .
apply : tan_inj; last by rewrite atanK tan0.
- by rewrite in_itv/= atan_gtNpi2 atan_ltpi2.
- by rewrite in_itv/= oppr_cp0 divr_gt0 ?pi_gt0 .
Qed .
Lemma atan1 : atan 1 = pi / 4 %:R :> R.
Proof .
apply : tan_inj; first 2 last .
by rewrite atanK tan_piquarter.
by rewrite in_itv/= atan_gtNpi2 atan_ltpi2.
rewrite in_itv/= -mulNr (lt_trans _ (_ : 0 < _ )) /=; last 2 first .
by rewrite mulNr oppr_cp0 divr_gt0 // pi_gt0.
by rewrite divr_gt0 ?pi_gt0 // ltr0n.
rewrite ltr_pdivr_mulr// -mulrA ltr_pmulr// ?pi_gt0 //.
by rewrite (natrM _ 2 2 ) mulrA mulVf// mul1r ltr1n.
Qed .
Lemma atanN x : atan (- x) = - atan x.
Proof .
apply : tan_inj; first by rewrite in_itv/= atan_ltpi2 atan_gtNpi2.
- by rewrite in_itv/= ltr_oppl opprK ltr_oppl andbC atan_ltpi2 atan_gtNpi2.
- by rewrite tanN !atanK.
Qed .
Lemma tanK : {in `](- (pi / 2 )), (pi / 2 )[ , cancel tan atan}.
Proof .
move => x xB; apply tan_inj => //; rewrite ?atanK //.
by rewrite in_itv/= atan_gtNpi2 atan_ltpi2.
Qed .
Lemma continuous_atan x : {for x, continuous atan}.
Proof .
rewrite -[x]atanK.
have /near_in_itv aI : atan x \in `](-(pi / 2 )), (pi / 2 )[.
suff : - (pi / 2 ) < atan x < pi / 2 by [].
by rewrite atan_gtNpi2 atan_ltpi2.
apply : nbhs_singleton (near_can_continuous _ _); last first .
by near=> z; apply /continuous_tan/lt0r_neq0/cos_gt0_pihalf; near: z.
by near=> z; apply : tanK; near: z.
Unshelve . all : by end_near. Qed .
Lemma cos_atan x : cos (atan x) = (Num.sqrt (1 + x ^+ 2 )) ^-1 .
Proof .
have cos_gt0 : 0 < cos (atan x).
by apply : cos_gt0_pihalf; rewrite atan_gtNpi2 atan_ltpi2.
have cosD0 : cos (atan x) != 0 by apply : lt0r_neq0.
have /eqP : cos (atan x) ^+2 = (Num.sqrt (1 + x ^+ 2 ))^-2 .
by rewrite -[LHS]invrK cos2_tan2 // atanK sqr_sqrtr // addr_ge0 // sqr_ge0.
rewrite -exprVn eqf_sqr => /orP[] /eqP // cosE.
move : cos_gt0; rewrite cosE ltNge; case /negP.
by rewrite oppr_le0 invr_ge0 sqrtr_ge0.
Qed .
Global Instance is_derive1_atan (x : R) : is_derive x 1 atan (1 + x ^+ 2 )^-1 .
Proof .
rewrite -{1 }[x]atanK.
have cosD0 : cos (atan x) != 0 .
by apply /lt0r_neq0/cos_gt0_pihalf; rewrite atan_gtNpi2 atan_ltpi2.
have /near_in_itv aI : atan x \in `](-(pi/2 )), (pi/2 )[.
suff : - (pi / 2 ) < atan x < pi / 2 by [].
by rewrite atan_gtNpi2 atan_ltpi2.
apply : (@is_derive_inverse R tan).
- by near=> z; apply : tanK; near: z.
- by near=> z; apply /continuous_tan/lt0r_neq0/cos_gt0_pihalf; near: z.
- by rewrite -[X in 1 + X ^+ 2 ]atanK -cos2_tan2 //; exact : is_derive_tan.
by apply /lt0r_neq0/(@lt_le_trans _ _ 1 ) => //; rewrite ler_addl sqr_ge0.
Unshelve . all : by end_near. Qed .
End Atan .