Module mathcomp.analysis.trigo
From HB Require Import structures.From mathcomp Require Import all_ssreflect ssralg ssrint ssrnum matrix.
From mathcomp Require Import interval rat.
From mathcomp Require Import mathcomp_extra boolp classical_sets functions.
From mathcomp Require Import reals ereal nsatz_realtype signed topology.
From mathcomp Require Import normedtype landau 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.
Lemma cvg_series_cvg_series_group (R : realFieldType) (f : R ^nat) k :
cvg (series f @ \oo) -> (0 < k)%N ->
[series \sum_(n * k <= i < n.+1 * k) f i]_n @ \oo --> lim (series f @ \oo).
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.
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 @ \oo) ->
(forall d, 0 < f (n + d.*2)%N + f (n + d.*2.+1)%N) ->
\sum_(0 <= i < n) f i < lim (series f @ \oo).
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) lerDl /= add0n.
by rewrite 2!big_cons big_nil addr0 -(addnC n) ltW// -addnS fn.
case=> N _ Nfn; have /Nfn/ltr_distlCDr : (N.+1.*2 + n >= N)%N.
by rewrite doubleS -addn2 -addnn -2!addnA leq_addr.
rewrite addrA => ffnfn.
have : lim (series f @ \oo) + 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 lerD2r.
by move/(lt_le_trans ffnfn); rewrite ltxx.
Qed.
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) lerDl /= add0n.
by rewrite 2!big_cons big_nil addr0 -(addnC n) ltW// -addnS fn.
case=> N _ Nfn; have /Nfn/ltr_distlCDr : (N.+1.*2 + n >= N)%N.
by rewrite doubleS -addn2 -addnn -2!addnA leq_addr.
rewrite addrA => ffnfn.
have : lim (series f @ \oo) + 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 lerD2r.
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.
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.
End alternating.
Definition sin_coeff {R : realType} (x : R) :=
[sequence (odd n)%:R * (-1) ^+ n.-1./2 * x ^+ n / n`!%:R]_n.
HB.lock Definition sin {R : realType} x : R := lim (series (sin_coeff x) @ \oo).
Canonical locked_sin := Unlockable sin.unlock.
Definition cos_coeff {R : realType} (x : R) :=
[sequence (~~ odd n)%:R * (-1)^n./2 * x ^+ n / n`!%:R]_n.
HB.lock Definition cos {R : realType} x : R := lim (series (cos_coeff x) @ \oo).
Canonical locked_cos := Unlockable cos.unlock.
Section CosSin.
Variable R : realType.
Implicit Types x y : R.
Lemma sin_coeffE x : sin_coeff x =
(fun n => (fun n => (odd n)%:R * (-1) ^+ n.-1./2 * (n`!%:R)^-1) n * x ^+ n).
Lemma sin_coeff_even n x : sin_coeff x n.*2 = 0.
Proof.
Lemma is_cvg_series_sin_coeff x : cvg (series (sin_coeff x) @ \oo).
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.
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.
Lemma sinE : @sin R = fun x =>
lim (pseries (fun n => (odd n)%:R * (-1) ^+ n.-1./2 * (n`!%:R)^-1) x @ \oo).
Proof.
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.
Lemma cvg_sin_coeff' x : series (sin_coeff' x) @ \oo --> sin x.
Proof.
rewrite unlock.
have /(@cvg_series_cvg_series_group _ _ 2) := @is_cvg_series_sin_coeff x.
move=> /(_ isT); apply: cvg_trans.
rewrite [X in _ --> series X @ \oo](_ : _ = (fun n => sin_coeff x n.*2.+1)).
rewrite [X in series X @ \oo --> _](_ : _ = (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.
have /(@cvg_series_cvg_series_group _ _ 2) := @is_cvg_series_sin_coeff x.
move=> /(_ isT); apply: cvg_trans.
rewrite [X in _ --> series X @ \oo](_ : _ = (fun n => sin_coeff x n.*2.+1)).
rewrite [X in series X @ \oo --> _](_ : _ = (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.
Lemma series_sin_coeff0 n : series (@sin_coeff R 0) n.+1 = 0.
Proof.
Lemma sin0 : sin 0 = 0 :> R.
Proof.
rewrite unlock.
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.
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.
Lemma cos_coeff_odd n x : cos_coeff x n.*2.+1 = 0.
Proof.
Lemma cos_coeff_2_0 : cos_coeff 2 0%N = 1 :> R.
Lemma cos_coeff_2_2 : cos_coeff 2 2%N = - 2%:R :> R.
Lemma cos_coeff_2_4 : cos_coeff 2 4%N = 2%:R / 3%:R :> R.
Proof.
Lemma cos_coeffE x :
cos_coeff x = (fun n => (fun n => (~~(odd n))%:R * (-1) ^+ n./2 *
(n`!%:R)^-1) n * x ^+ n).
Lemma is_cvg_series_cos_coeff x : cvg (series (cos_coeff x) @ \oo).
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.
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.
Lemma cosE : @cos R = fun x =>
lim (series (fun n =>
(fun n => (~~(odd n))%:R * (-1)^+ n./2 * (n`!%:R)^-1) n
* x ^+ n) @ \oo).
Proof.
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.
by rewrite (half_bit_double n false).
Qed.
Lemma cvg_cos_coeff' x : series (cos_coeff' x) @ \oo --> cos x.
Proof.
rewrite unlock.
have /(@cvg_series_cvg_series_group _ _ 2) := @is_cvg_series_cos_coeff x.
move=> /(_ isT); apply: cvg_trans.
rewrite [X in _ --> series X @ \oo](_ : _ = (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 @ \oo --> _](_ : _ = (fun n => cos_coeff x n.*2)) //.
by rewrite funeqE => n; exact: cos_coeff'E.
Qed.
have /(@cvg_series_cvg_series_group _ _ 2) := @is_cvg_series_cos_coeff x.
move=> /(_ isT); apply: cvg_trans.
rewrite [X in _ --> series X @ \oo](_ : _ = (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 @ \oo --> _](_ : _ = (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.
Lemma series_cos_coeff0 n : series (cos_coeff 0) n.+1 = 1 :> R.
Proof.
Lemma cos0 : cos 0 = 1 :> R.
Proof.
rewrite unlock.
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.
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 R) (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.
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 R) x 1.
Proof.
Lemma continuous_sin : continuous (@sin R).
Proof.
Global Instance is_derive_cos x : is_derive x 1 (@cos R) (- 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.
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 R) x 1.
Proof.
Lemma continuous_cos : continuous (@cos R).
Proof.
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.
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.
Lemma cos_geN1 x : -1 <= cos x.
Proof.
Lemma cos_le1 x : cos x <= 1.
Proof.
Lemma sin_max x : `| sin x | <= 1.
Proof.
Lemma sin_geN1 x : -1 <= sin x.
Proof.
Lemma sin_le1 x : sin x <= 1.
Proof.
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.
Lemma sinD x y : sin (x + y) = sin x * cos y + cos x * sin y.
Proof.
Lemma cosD x y : cos (x + y) = cos x * cos y - sin x * sin y.
Proof.
Lemma sin2cos2 x : sin x ^+ 2 = 1 - cos x ^+ 2.
Lemma cos2sin2 x : cos x ^+ 2 = 1 - sin x ^+ 2.
Lemma sin_mulr2n x : sin (x *+ 2) = (cos x * sin x) *+ 2.
Lemma cos_mulr2n x : cos (x *+ 2) = cos x ^+2 *+ 2 - 1.
Fact sinN_cosN x :
(sin (- x) + sin x) ^+ 2 + (cos (- x) - cos x) ^+ 2 = 0.
Proof.
Lemma sinN x : sin (- x) = - sin x.
Proof.
Lemma cosN x : cos (- x) = cos x.
Proof.
Lemma sin_sg x y : sin (Num.sg x * y) = Num.sg x * sin y.
Lemma cos_sg x y : x != 0 -> cos (Num.sg x * y) = cos y.
Lemma cosB x y : cos (x - y) = cos x * cos y + sin x * sin y.
Lemma sinB x y : sin (x - y) = sin x * cos y - cos x * sin y.
Lemma norm_cos_eq1 x : (`|cos x| == 1) = (sin x == 0).
Proof.
Lemma norm_sin_eq1 x : (`|sin x| == 1) = (cos x == 0).
Proof.
Lemma cos1sin0 x : `|cos x| = 1 -> sin x = 0.
Proof.
Lemma sin1cos0 x : `|sin x| = 1 -> cos x = 0.
Proof.
Lemma sin0cos1 x : sin x = 0 -> `|cos x| = 1.
Proof.
Lemma cos_norm x : cos `|x| = cos x.
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].
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_pM2l//.
rewrite factS factS 2!natrM mulrA invfM !mulrA.
rewrite ltr_pdivrMr ?ltr0n ?fact_gt0// mulVf ?pnatr_eq0 ?gtn_eqF ?fact_gt0//.
rewrite ltr_pdivrMr ?mul1r //.
by rewrite expr2 -!natrM ltr_nat !mulSn !add2n mul0n !addnS.
Qed.
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_pM2l//.
rewrite factS factS 2!natrM mulrA invfM !mulrA.
rewrite ltr_pdivrMr ?ltr0n ?fact_gt0// mulVf ?pnatr_eq0 ?gtn_eqF ?fact_gt0//.
rewrite ltr_pdivrMr ?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.
apply: 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_pM2r; last by rewrite invr_gt0 (ltr_nat _ 0) ffact_gt0 leq_addl.
rewrite {}/v !addnS addn0 !ffactnS ffactn0 muln1 /= natrM.
by rewrite (ltr_pM (ltW _ ) (ltW _)) // (lt_le_trans x_lt2) // ler_nat.
Qed.
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.
apply: 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_pM2r; last by rewrite invr_gt0 (ltr_nat _ 0) ffact_gt0 leq_addl.
rewrite {}/v !addnS addn0 !ffactnS ffactn0 muln1 /= natrM.
by rewrite (ltr_pM (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_pV2 ?posrE ?ltr0n// ltr_nat.
apply: 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_pV2 ?posrE ?ltr0n ?fact_gt0//.
by rewrite ltr_nat ltn_pfact//ltn_double doubleS.
Qed.
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_pV2 ?posrE ?ltr0n// ltr_nat.
apply: 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_pV2 ?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.
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.
move: xLy; rewrite le_eqVlt => /predU1P[//|xLLs].
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.
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.
move: xLy; rewrite le_eqVlt => /predU1P[//|xLLs].
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.
#[deprecated(note="Use pihalf_ge1 and pihalf_lt2 instead")]
Lemma pihalf_02 : 0 < pi / 2 < 2.
Proof.
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.
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.
Lemma pihalf_lt2 : pi / 2 < 2.
Lemma pi_ge2 : 2 <= pi.
Proof.
Lemma pi_gt0 : 0 < pi
Proof.
Lemma pi_ge0 : 0 <= pi
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.
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 ltrNl andbC [-- _ < _]ltrNl 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.
case: (leP 0 x) => [/Hw//| x_lt_0].
rewrite -{-1}[x]opprK ltrNl andbC [-- _ < _]ltrNl 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.
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.
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 2!le_eqVlt => /andP[/predU1P[<-|?]]; first by rewrite cosN cos_pihalf.
move=> /predU1P[->|?]; first by rewrite cos_pihalf.
by apply/ltW/cos_gt0_pihalf/andP.
Qed.
move=> /predU1P[->|?]; first by rewrite cos_pihalf.
by apply/ltW/cos_gt0_pihalf/andP.
Qed.
Lemma cospi : cos pi = - 1.
Proof.
Lemma sinpi : sin pi = 0.
Lemma cos2pi : cos (pi *+ 2) = 1.
Lemma sin2pi : sin (pi *+ 2) = 0.
Lemma sinDpi : alternating sin pi.
Lemma cosDpi : alternating cos pi.
Lemma sinD2pi : periodic sin (pi *+ 2).
Lemma cosD2pi : periodic cos (pi *+ 2).
Lemma cosDpihalf a : cos (a + pi / 2) = - sin a.
Proof.
Lemma cosBpihalf a : cos (a - pi / 2) = sin a.
Proof.
Lemma sinDpihalf a : sin (a + pi / 2) = cos a.
Proof.
Lemma sinBpihalf a : sin (a - pi / 2) = - cos a.
Proof.
Lemma sin_ge0_pi x : 0 <= x <= pi -> 0 <= sin x.
Proof.
Lemma sin_gt0_pi x : 0 < x < pi -> 0 < sin x.
Proof.
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]] //.
exact/continuous_subspaceT/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]] //.
exact/continuous_subspaceT/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.
move: (xLy); rewrite le_eqVlt => /predU1P[->|xLLs]; first by rewrite ltxx.
rewrite xLLs -subr_gt0 -opprB; rewrite -subr_gt0 in xLLs; apply/idP.
have [x1|z /itvP zI ->] := @MVT_segment _ cos (- sin) _ _ xLy.
exact/continuous_subspaceT/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.
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]] //.
exact/continuous_subspaceT/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]] //.
exact/continuous_subspaceT/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.
move: (xLy); rewrite le_eqVlt => /predU1P[->|xLLs]; first by rewrite ltxx.
rewrite xLLs -subr_gt0 -opprB; rewrite -subr_gt0 in xLLs; apply/idP.
have [x1|z /itvP zI ->] := @MVT_segment _ cos (- sin) _ _ xLy.
exact/continuous_subspaceT/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.
Lemma cos_inj : {in `[0,pi] &, injective (@cos R)}.
Proof.
Lemma sin_inj : {in `[(- (pi/2)), (pi/2)] &, injective sin}.
Proof.
End Pi.
Arguments pi {R}.
Section Tan.
Variable R : realType.
Definition tan (x : R) := sin x / cos x.
Lemma tan0 : tan 0 = 0 :> R.
Lemma tanpi : tan pi = 0.
Lemma tanN x : tan (- x) = - tan x.
Lemma tanD x y : cos x != 0 -> cos y != 0 ->
tan (x + y) = (tan x + tan y) / (1 - tan x * tan y).
Proof.
Lemma tan_mulr2n x : cos x != 0 -> tan (x *+ 2) = tan x *+ 2 / (1 - tan x ^+ 2).
Lemma cos2_tan2 x : cos x != 0 -> (cos x) ^- 2 = 1 + tan x ^+ 2.
Proof.
Lemma tan_pihalf : tan (pi / 2) = 0.
Proof.
Lemma tan_piquarter : tan (pi / 4%:R) = 1.
Proof.
Lemma tanDpi x : tan (x + pi) = tan x.
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.
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.
Lemma derivable_tan x : cos x != 0 -> derivable tan x 1.
Proof.
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.
move: (xLy); rewrite le_eqVlt => /predU1P[->|xLLs]; first by rewrite ltxx.
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.
case: (lerP x y) => [/H //->//|yLx].
by rewrite !ltNge ltW ?(ltW yLx) // H // ltW.
move: (xLy); rewrite le_eqVlt => /predU1P[->|xLLs]; first by rewrite ltxx.
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}.
End Tan.
Arguments tan {R}.
#[global] Hint Extern 0 (is_derive _ _ tan _) =>
(eapply is_derive_tan; first by []) : typeclass_instances.
HB.lock Definition acos {R : realType} (x : R) : R :=
get [set y | 0 <= y <= pi /\ cos y = x].
Canonical locked_acos := Unlockable acos.unlock.
Section Acos.
Variable R : realType.
Implicit Type x : R.
Lemma acos_def x :
-1 <= x <= 1 -> 0 <= acos x <= pi /\ cos (acos x) = x.
Proof.
move=> xB; rewrite unlock /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 ltrD2r -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.
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 ltrD2r -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.
Lemma acos_lepi x : -1 <= x <= 1 -> acos x <= pi.
Lemma acosK : {in `[(-1),1], cancel (@acos R) cos}.
Lemma acos_gt0 x : -1 <= x < 1 -> 0 < acos x.
Proof.
Lemma acos_ltpi x : -1 < x <= 1 -> acos x < pi.
Proof.
Lemma cosK : {in `[0, pi], cancel (@cos R) (@acos R)}.
Proof.
Lemma acos1 : acos (1 : R) = 0.
Lemma acos0 : acos (0 : R) = pi / 2%:R.
Proof.
Lemma acosN a : -1 <= a <= 1 -> acos (- a) = pi - acos a :> R.
Proof.
Lemma acosN1 : acos (- 1) = (pi : R).
Lemma cosKN x : - pi <= x <= 0 -> acos (cos x) = - x.
Lemma sin_acos x : -1 <= x <= 1 -> sin (acos x) = Num.sqrt (1 - x^+2).
Proof.
Lemma continuous_acos x : -1 < x < 1 -> {for x, continuous (@acos R)}.
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_itvoo aI : acos x \in `]0, pi[.
by rewrite in_itv/= acos_gt0 ?ltW //= acos_ltpi // ltW ?andbT.
near=> z; apply: cosK.
suff /itvP zI : z \in `]0, pi[ by rewrite in_itv/= ltW zI.
by near: z.
Unshelve. all: by end_near. Qed.
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_itvoo aI : acos x \in `]0, pi[.
by rewrite in_itv/= acos_gt0 ?ltW //= acos_ltpi // ltW ?andbT.
near=> z; apply: cosK.
suff /itvP zI : z \in `]0, pi[ by rewrite in_itv/= ltW zI.
by near: z.
Unshelve. all: by end_near. Qed.
Lemma is_derive1_acos x :
-1 < x < 1 -> is_derive x 1 (@acos R) (- (Num.sqrt (1 - x ^+ 2))^-1).
Proof.
move=> /andP[x_gtN1 x_lt1]; rewrite -sin_acos ?ltW // -invrN.
rewrite -{1}[x]acosK; last by rewrite in_itv /= ?ltW.
have /near_in_itvoo aI : acos x \in `]0, pi[.
by rewrite in_itv/= acos_gt0 ?ltW //= acos_ltpi // x_gtN1 ltW.
apply: (@is_derive_inverse R cos).
- near=> z; apply: cosK.
suff /itvP zI : z \in `]0, pi[ by rewrite in_itv/= ?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.
rewrite -{1}[x]acosK; last by rewrite in_itv /= ?ltW.
have /near_in_itvoo aI : acos x \in `]0, pi[.
by rewrite in_itv/= acos_gt0 ?ltW //= acos_ltpi // x_gtN1 ltW.
apply: (@is_derive_inverse R cos).
- near=> z; apply: cosK.
suff /itvP zI : z \in `]0, pi[ by rewrite in_itv/= ?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.
HB.lock Definition asin {R : realType} (x : R) : R :=
get [set y | -(pi / 2) <= y <= pi / 2 /\ sin y = x].
Canonical locked_asin := Unlockable asin.unlock.
Section Asin.
Variable R : realType.
Implicit Type x : R.
Lemma asin_def x :
-1 <= x <= 1 -> -(pi / 2) <= asin x <= pi / 2 /\ sin (asin x) = x.
Proof.
move=> xB; rewrite unlock /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 ltrD2r -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.
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 ltrD2r -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.
Lemma asin_lepi2 x : -1 <= x <= 1 -> asin x <= pi / 2.
Lemma asinK : {in `[(-1),1], cancel (@asin R) sin}.
Lemma asin_ltpi2 x : -1 <= x < 1 -> asin x < pi/2.
Proof.
Lemma asin_gtNpi2 x : -1 < x <= 1 -> - (pi / 2) < asin x.
Proof.
Lemma sinK : {in `[(- (pi / 2)), pi / 2], cancel (@sin R) (@asin R)}.
Proof.
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.
by apply: cos_ge0_pihalf; rewrite asin_lepi2 // asin_geNpi2.
Qed.
Lemma continuous_asin x : -1 < x < 1 -> {for x, continuous (@asin R)}.
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_itvoo aI : asin x \in `](-(pi/2)), (pi/2)[.
by rewrite in_itv/= 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.
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_itvoo aI : asin x \in `](-(pi/2)), (pi/2)[.
by rewrite in_itv/= 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 :
-1 < x < 1 -> is_derive x 1 (@asin R) (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_itvoo aI : asin x \in `](-(pi/2)), (pi/2)[.
by rewrite in_itv/= 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.
rewrite -{1}[x]asinK; last by have : -1 <= x <= 1 by rewrite ltW // ltW.
have /near_in_itvoo aI : asin x \in `](-(pi/2)), (pi/2)[.
by rewrite in_itv/= 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.
HB.lock Definition atan {R : realType} (x : R) : R :=
get [set y | -(pi / 2) < y < pi / 2 /\ tan y = x].
Canonical locked_atan := Unlockable atan.unlock.
Section Atan.
Variable R : realType.
Implicit Type x : R.
Lemma atan_def x : -(pi / 2) < atan x < pi / 2 /\ tan (atan x) = x.
Proof.
rewrite unlock /atan; case: xgetP => //= He.
pose x1 := Num.sqrt (1 + x ^+ 2)^-1.
have ox2_gt0 : 0 < 1 + x^2 by exact/ltr_pwDl/sqr_ge0.
have ox2_ge0 : 0 <= 1 + x^2 by rewrite ltW.
have x1B : -1 <= x1 <= 1.
rewrite -ler_norml /x1 ger0_norm ?sqrt_ge0// -[leRHS]sqrtr1.
by rewrite ler_psqrt ?qualifE/= ?invr_gte0// invf_le1// lerDl sqr_ge0.
case: (He (Num.sg x * acos x1)); split; last first.
have [->|xD0] := eqVneq x 0; first by rewrite sgr0 mul0r tan0.
rewrite /tan sin_sg cos_sg // acosK ?sin_acos// /x1 sqr_sqrtr// ?invr_ge0//.
rewrite -[X in 1 - X]div1r -[X in X - _]divr1// -mulNr addf_div ?lt0r_neq0//.
rewrite mul1r mulr1 [X in X - 1]addrC addrK// sqrtrM ?sqr_ge0// sqrtrV//.
rewrite 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.
have [->|xD0] := eqVneq x 0; 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 ltW//= ler_pdivrMr// ler_pMr ?pi_gt0// ler1n.
by rewrite cos_pihalf acosK// sqrtr_gt0 ?invr_gt0.
Qed.
pose x1 := Num.sqrt (1 + x ^+ 2)^-1.
have ox2_gt0 : 0 < 1 + x^2 by exact/ltr_pwDl/sqr_ge0.
have ox2_ge0 : 0 <= 1 + x^2 by rewrite ltW.
have x1B : -1 <= x1 <= 1.
rewrite -ler_norml /x1 ger0_norm ?sqrt_ge0// -[leRHS]sqrtr1.
by rewrite ler_psqrt ?qualifE/= ?invr_gte0// invf_le1// lerDl sqr_ge0.
case: (He (Num.sg x * acos x1)); split; last first.
have [->|xD0] := eqVneq x 0; first by rewrite sgr0 mul0r tan0.
rewrite /tan sin_sg cos_sg // acosK ?sin_acos// /x1 sqr_sqrtr// ?invr_ge0//.
rewrite -[X in 1 - X]div1r -[X in X - _]divr1// -mulNr addf_div ?lt0r_neq0//.
rewrite mul1r mulr1 [X in X - 1]addrC addrK// sqrtrM ?sqr_ge0// sqrtrV//.
rewrite 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.
have [->|xD0] := eqVneq x 0; 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 ltW//= ler_pdivrMr// ler_pMr ?pi_gt0// ler1n.
by rewrite cos_pihalf acosK// sqrtr_gt0 ?invr_gt0.
Qed.
Lemma atan_gtNpi2 x : - (pi / 2) < atan x.
Lemma atan_ltpi2 x : atan x < pi / 2.
Lemma atanK : cancel (@atan R) tan.
Proof.
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.
- 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/= -divrN !ltr_pM2l ?pi_gt0// (lt_trans (_ : _ < 0))//=.
by rewrite ltf_pV2 ?qualifE//= ltr_nat.
Qed.
by rewrite atanK tan_piquarter.
by rewrite in_itv/= atan_gtNpi2 atan_ltpi2.
rewrite in_itv/= -divrN !ltr_pM2l ?pi_gt0// (lt_trans (_ : _ < 0))//=.
by rewrite ltf_pV2 ?qualifE//= ltr_nat.
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/= ltrNl opprK ltrNl andbC atan_ltpi2 atan_gtNpi2.
- by rewrite tanN !atanK.
Qed.
- by rewrite in_itv/= ltrNl opprK ltrNl andbC atan_ltpi2 atan_gtNpi2.
- by rewrite tanN !atanK.
Qed.
Lemma tanK : {in `](- (pi / 2)), (pi / 2)[ , cancel (@tan R) (@atan R)}.
Proof.
move=> x xB; apply tan_inj => //; rewrite ?atanK//.
by rewrite in_itv/= atan_gtNpi2 atan_ltpi2.
Qed.
by rewrite in_itv/= atan_gtNpi2 atan_ltpi2.
Qed.
Lemma continuous_atan x : {for x, continuous (@atan R)}.
Proof.
rewrite -[x]atanK.
have /near_in_itvoo aI : atan x \in `](-(pi / 2)), (pi / 2)[.
by rewrite in_itv/= 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.
have /near_in_itvoo aI : atan x \in `](-(pi / 2)), (pi / 2)[.
by rewrite in_itv/= 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.
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 : 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_itvoo aI : atan x \in `](-(pi/2)), (pi/2)[.
by rewrite in_itv/= 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.
exact/lt0r_neq0/ltr_pwDl/sqr_ge0.
Unshelve. all: by end_near. Qed.
have cosD0 : cos (atan x) != 0.
by apply/lt0r_neq0/cos_gt0_pihalf; rewrite atan_gtNpi2 atan_ltpi2.
have /near_in_itvoo aI : atan x \in `](-(pi/2)), (pi/2)[.
by rewrite in_itv/= 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.
exact/lt0r_neq0/ltr_pwDl/sqr_ge0.
Unshelve. all: by end_near. Qed.
Lemma derive1_atan : atan^`() =1 (fun x => (1 + x ^+ 2)^-1).
Proof.
Lemma lt_atan : {homo (@atan R) : x y / x < y}.
Proof.
move=> x y xy; rewrite -subr_gt0.
have datan z : z \in `]x, y[ -> is_derive z 1 atan (1 + z ^+ 2)^-1.
by move=> _; exact: is_derive1_atan.
have catan : {within `[x, y], continuous atan}.
by apply: derivable_within_continuous => z _; exact: ex_derive.
have [c _ ->] := MVT xy datan catan.
by rewrite mulr_gt0// ?subr_gt0// invr_gt0// ltr_wpDr// sqr_ge0.
Qed.
have datan z : z \in `]x, y[ -> is_derive z 1 atan (1 + z ^+ 2)^-1.
by move=> _; exact: is_derive1_atan.
have catan : {within `[x, y], continuous atan}.
by apply: derivable_within_continuous => z _; exact: ex_derive.
have [c _ ->] := MVT xy datan catan.
by rewrite mulr_gt0// ?subr_gt0// invr_gt0// ltr_wpDr// sqr_ge0.
Qed.
Lemma le_atan : {homo @atan R : x y / x <= y}.
Lemma cvgy_atan : (@atan R) x @[x --> +oo] --> pi / 2.
Proof.
have ? : ubound (range (@atan R)) (pi / 2).
by move=> _ /= [x _ <-]; exact/ltW/atan_ltpi2.
rewrite (_ : pi / 2 = sup (range atan)).
by apply/(nondecreasing_cvgr le_atan); exists (pi / 2).
apply/eqP; rewrite eq_le; apply/andP; split; last first.
by apply: sup_le_ub => //; exists 0, 0 => //; exact: atan0.
have -> : pi / 2 = sup `[0, pi / 2[ :> R.
by rewrite real_interval.sup_itv// bnd_simp divr_gt0// pi_gt0.
apply: le_sup; last 2 first.
- by exists 0; rewrite /= in_itv/= lexx/= divr_gt0// pi_gt0.
- split; first by exists 0, 0 => //; rewrite atan0.
by exists (pi / 2) => _ [x _ <-]; exact/ltW/atan_ltpi2.
move=> x/= /[!in_itv]/= /andP[x0 xpi2].
apply/downP; exists (atan (tan x)) => /=; first by exists (tan x).
rewrite tanK// in_itv/= xpi2 andbT (lt_le_trans _ x0)//.
by rewrite ltrNl oppr0 divr_gt0// pi_gt0.
Qed.
by move=> _ /= [x _ <-]; exact/ltW/atan_ltpi2.
rewrite (_ : pi / 2 = sup (range atan)).
by apply/(nondecreasing_cvgr le_atan); exists (pi / 2).
apply/eqP; rewrite eq_le; apply/andP; split; last first.
by apply: sup_le_ub => //; exists 0, 0 => //; exact: atan0.
have -> : pi / 2 = sup `[0, pi / 2[ :> R.
by rewrite real_interval.sup_itv// bnd_simp divr_gt0// pi_gt0.
apply: le_sup; last 2 first.
- by exists 0; rewrite /= in_itv/= lexx/= divr_gt0// pi_gt0.
- split; first by exists 0, 0 => //; rewrite atan0.
by exists (pi / 2) => _ [x _ <-]; exact/ltW/atan_ltpi2.
move=> x/= /[!in_itv]/= /andP[x0 xpi2].
apply/downP; exists (atan (tan x)) => /=; first by exists (tan x).
rewrite tanK// in_itv/= xpi2 andbT (lt_le_trans _ x0)//.
by rewrite ltrNl oppr0 divr_gt0// pi_gt0.
Qed.
End Atan.