@@ -21,26 +21,27 @@ The result of `arctan x + arctan y` is given by `arctan_add`, `arctan_add_eq_add
21
21
22
22
noncomputable section
23
23
24
- namespace Real
25
-
26
24
open Set Filter
25
+ open scoped Topology
27
26
28
- open scoped Topology Real
27
+ namespace Real
29
28
30
- theorem tan_add {x y : ℝ}
29
+ variable {x y : ℝ}
30
+
31
+ theorem tan_add
31
32
(h : ((∀ k : ℤ, x ≠ (2 * k + 1 ) * π / 2 ) ∧ ∀ l : ℤ, y ≠ (2 * l + 1 ) * π / 2 ) ∨
32
33
(∃ k : ℤ, x = (2 * k + 1 ) * π / 2 ) ∧ ∃ l : ℤ, y = (2 * l + 1 ) * π / 2 ) :
33
34
tan (x + y) = (tan x + tan y) / (1 - tan x * tan y) := by
34
35
simpa only [← Complex.ofReal_inj, Complex.ofReal_sub, Complex.ofReal_add, Complex.ofReal_div,
35
36
Complex.ofReal_mul, Complex.ofReal_tan] using
36
37
@Complex.tan_add (x : ℂ) (y : ℂ) (by convert h <;> norm_cast)
37
38
38
- theorem tan_add' {x y : ℝ}
39
+ theorem tan_add'
39
40
(h : (∀ k : ℤ, x ≠ (2 * k + 1 ) * π / 2 ) ∧ ∀ l : ℤ, y ≠ (2 * l + 1 ) * π / 2 ) :
40
41
tan (x + y) = (tan x + tan y) / (1 - tan x * tan y) :=
41
42
tan_add (Or.inl h)
42
43
43
- theorem tan_two_mul {x : ℝ} : tan (2 * x) = 2 * tan x / (1 - tan x ^ 2 ) := by
44
+ theorem tan_two_mul : tan (2 * x) = 2 * tan x / (1 - tan x ^ 2 ) := by
44
45
have := @Complex.tan_two_mul x
45
46
norm_cast at *
46
47
@@ -110,7 +111,7 @@ theorem arctan_mem_Ioo (x : ℝ) : arctan x ∈ Ioo (-(π / 2)) (π / 2) :=
110
111
theorem range_arctan : range arctan = Ioo (-(π / 2 )) (π / 2 ) :=
111
112
((EquivLike.surjective _).range_comp _).trans Subtype.range_coe
112
113
113
- theorem arctan_tan {x : ℝ} (hx₁ : -(π / 2 ) < x) (hx₂ : x < π / 2 ) : arctan (tan x) = x :=
114
+ theorem arctan_tan (hx₁ : -(π / 2 ) < x) (hx₂ : x < π / 2 ) : arctan (tan x) = x :=
114
115
Subtype.ext_iff.1 <| tanOrderIso.symm_apply_apply ⟨x, hx₁, hx₂⟩
115
116
116
117
theorem cos_arctan_pos (x : ℝ) : 0 < cos (arctan x) :=
@@ -134,7 +135,7 @@ theorem neg_pi_div_two_lt_arctan (x : ℝ) : -(π / 2) < arctan x :=
134
135
theorem arctan_eq_arcsin (x : ℝ) : arctan x = arcsin (x / √(1 + x ^ 2 )) :=
135
136
Eq.symm <| arcsin_eq_of_sin_eq (sin_arctan x) (mem_Icc_of_Ioo <| arctan_mem_Ioo x)
136
137
137
- theorem arcsin_eq_arctan {x : ℝ} (h : x ∈ Ioo (-(1 : ℝ)) 1 ) :
138
+ theorem arcsin_eq_arctan (h : x ∈ Ioo (-(1 : ℝ)) 1 ) :
138
139
arcsin x = arctan (x / √(1 - x ^ 2 )) := by
139
140
rw_mod_cast [arctan_eq_arcsin, div_pow, sq_sqrt, one_add_div, div_div, ← sqrt_mul,
140
141
mul_div_cancel₀, sub_add_cancel, sqrt_one, div_one] <;> simp at h <;> nlinarith [h.1 , h.2 ]
@@ -145,17 +146,28 @@ theorem arctan_zero : arctan 0 = 0 := by simp [arctan_eq_arcsin]
145
146
@[mono]
146
147
theorem arctan_strictMono : StrictMono arctan := tanOrderIso.symm.strictMono
147
148
149
+ theorem arctan_mono : Monotone arctan := arctan_strictMono.monotone
150
+
148
151
@[gcongr]
149
- lemma arctan_lt_arctan {x y : ℝ} (hxy : x < y) : arctan x < arctan y := arctan_strictMono hxy
152
+ lemma arctan_lt_arctan (hxy : x < y) : arctan x < arctan y := arctan_strictMono hxy
153
+
154
+ @[simp]
155
+ theorem arctan_lt_arctan_iff : arctan x < arctan y ↔ x < y := arctan_strictMono.lt_iff_lt
150
156
151
157
@[gcongr]
152
- lemma arctan_le_arctan {x y : ℝ} (hxy : x ≤ y) : arctan x ≤ arctan y :=
158
+ lemma arctan_le_arctan (hxy : x ≤ y) : arctan x ≤ arctan y :=
153
159
arctan_strictMono.monotone hxy
154
160
161
+ @[simp]
162
+ theorem arctan_le_arctan_iff : arctan x ≤ arctan y ↔ x ≤ y := arctan_strictMono.le_iff_le
163
+
155
164
theorem arctan_injective : arctan.Injective := arctan_strictMono.injective
156
165
157
166
@[simp]
158
- theorem arctan_eq_zero_iff {x : ℝ} : arctan x = 0 ↔ x = 0 :=
167
+ theorem arctan_inj : arctan x = arctan y ↔ x = y := arctan_injective.eq_iff
168
+
169
+ @[simp]
170
+ theorem arctan_eq_zero_iff : arctan x = 0 ↔ x = 0 :=
159
171
.trans (by rw [arctan_zero]) arctan_injective.eq_iff
160
172
161
173
theorem tendsto_arctan_atTop : Tendsto arctan atTop (𝓝[<] (π / 2 )) :=
@@ -164,62 +176,85 @@ theorem tendsto_arctan_atTop : Tendsto arctan atTop (𝓝[<] (π / 2)) :=
164
176
theorem tendsto_arctan_atBot : Tendsto arctan atBot (𝓝[>] (-(π / 2 ))) :=
165
177
tendsto_Ioo_atBot.mp tanOrderIso.symm.tendsto_atBot
166
178
167
- theorem arctan_eq_of_tan_eq {x y : ℝ} (h : tan x = y) (hx : x ∈ Ioo (-(π / 2 )) (π / 2 )) :
179
+ theorem arctan_eq_of_tan_eq (h : tan x = y) (hx : x ∈ Ioo (-(π / 2 )) (π / 2 )) :
168
180
arctan y = x :=
169
181
injOn_tan (arctan_mem_Ioo _) hx (by rw [tan_arctan, h])
170
182
171
183
@[simp]
172
184
theorem arctan_one : arctan 1 = π / 4 :=
173
185
arctan_eq_of_tan_eq tan_pi_div_four <| by constructor <;> linarith [pi_pos]
174
186
187
+ @[simp]
188
+ theorem arctan_eq_pi_div_four : arctan x = π / 4 ↔ x = 1 := arctan_injective.eq_iff' arctan_one
189
+
175
190
@[simp]
176
191
theorem arctan_neg (x : ℝ) : arctan (-x) = -arctan x := by simp [arctan_eq_arcsin, neg_div]
177
192
178
- theorem arctan_eq_arccos {x : ℝ} (h : 0 ≤ x) : arctan x = arccos (√(1 + x ^ 2 ))⁻¹ := by
193
+ @[simp]
194
+ theorem arctan_eq_neg_pi_div_four : arctan x = -(π / 4 ) ↔ x = -1 :=
195
+ arctan_injective.eq_iff' <| by rw [arctan_neg, arctan_one]
196
+
197
+ @[simp]
198
+ theorem arctan_pos : 0 < arctan x ↔ 0 < x := by
199
+ simpa only [arctan_zero] using arctan_lt_arctan_iff (x := 0 )
200
+
201
+ @[simp]
202
+ theorem arctan_lt_zero : arctan x < 0 ↔ x < 0 := by
203
+ simpa only [arctan_zero] using arctan_lt_arctan_iff (y := 0 )
204
+
205
+ @[simp]
206
+ theorem arctan_nonneg : 0 ≤ arctan x ↔ 0 ≤ x := by
207
+ simpa only [arctan_zero] using arctan_le_arctan_iff (x := 0 )
208
+
209
+ @[simp]
210
+ theorem arctan_le_zero : arctan x ≤ 0 ↔ x ≤ 0 := by
211
+ simpa only [arctan_zero] using arctan_le_arctan_iff (y := 0 )
212
+
213
+ theorem arctan_eq_arccos (h : 0 ≤ x) : arctan x = arccos (√(1 + x ^ 2 ))⁻¹ := by
179
214
rw [arctan_eq_arcsin, arccos_eq_arcsin]; swap; · exact inv_nonneg.2 (sqrt_nonneg _)
180
215
congr 1
181
216
rw_mod_cast [← sqrt_inv, sq_sqrt, ← one_div, one_sub_div, add_sub_cancel_left, sqrt_div,
182
217
sqrt_sq h]
183
218
all_goals positivity
184
219
185
220
-- The junk values for `arccos` and `sqrt` make this true even for `1 < x`.
186
- theorem arccos_eq_arctan {x : ℝ} (h : 0 < x) : arccos x = arctan (√(1 - x ^ 2 ) / x) := by
221
+ theorem arccos_eq_arctan (h : 0 < x) : arccos x = arctan (√(1 - x ^ 2 ) / x) := by
187
222
rw [arccos, eq_comm]
188
223
refine arctan_eq_of_tan_eq ?_ ⟨?_, ?_⟩
189
224
· rw_mod_cast [tan_pi_div_two_sub, tan_arcsin, inv_div]
190
225
· linarith only [arcsin_le_pi_div_two x, pi_pos]
191
226
· linarith only [arcsin_pos.2 h]
192
227
193
- theorem arctan_inv_of_pos {x : ℝ} (h : 0 < x) : arctan x⁻¹ = π / 2 - arctan x := by
228
+ theorem arctan_inv_of_pos (h : 0 < x) : arctan x⁻¹ = π / 2 - arctan x := by
194
229
rw [← arctan_tan (x := _ - _), tan_pi_div_two_sub, tan_arctan]
195
230
· norm_num
196
231
exact (arctan_lt_pi_div_two x).trans (half_lt_self_iff.mpr pi_pos)
197
232
· rw [sub_lt_self_iff, ← arctan_zero]
198
233
exact tanOrderIso.symm.strictMono h
199
234
200
- theorem arctan_inv_of_neg {x : ℝ} (h : x < 0 ) : arctan x⁻¹ = -(π / 2 ) - arctan x := by
235
+ theorem arctan_inv_of_neg (h : x < 0 ) : arctan x⁻¹ = -(π / 2 ) - arctan x := by
201
236
have := arctan_inv_of_pos (neg_pos.mpr h)
202
237
rwa [inv_neg, arctan_neg, neg_eq_iff_eq_neg, neg_sub', arctan_neg, neg_neg] at this
203
238
204
239
section ArctanAdd
205
240
206
- lemma arctan_ne_mul_pi_div_two {x : ℝ} : ∀ (k : ℤ), arctan x ≠ (2 * k + 1 ) * π / 2 := by
241
+ lemma arctan_ne_mul_pi_div_two : ∀ (k : ℤ), arctan x ≠ (2 * k + 1 ) * π / 2 := by
207
242
by_contra!
208
243
obtain ⟨k, h⟩ := this
209
244
obtain ⟨lb, ub⟩ := arctan_mem_Ioo x
210
245
rw [h, neg_eq_neg_one_mul, mul_div_assoc, mul_lt_mul_right (by positivity)] at lb
211
246
rw [h, ← one_mul (π / 2 ), mul_div_assoc, mul_lt_mul_right (by positivity)] at ub
212
247
norm_cast at lb ub; change -1 < _ at lb; omega
213
248
214
- lemma arctan_add_arctan_lt_pi_div_two {x y : ℝ} (h : x * y < 1 ) : arctan x + arctan y < π / 2 := by
249
+ lemma arctan_add_arctan_lt_pi_div_two (h : x * y < 1 ) : arctan x + arctan y < π / 2 := by
215
250
rcases le_or_gt y 0 with hy | hy
216
251
· rw [← add_zero (π / 2 ), ← arctan_zero]
217
252
exact add_lt_add_of_lt_of_le (arctan_lt_pi_div_two _) (tanOrderIso.symm.monotone hy)
218
253
· rw [← lt_div_iff₀ hy, ← inv_eq_one_div] at h
219
254
replace h : arctan x < arctan y⁻¹ := tanOrderIso.symm.strictMono h
220
255
rwa [arctan_inv_of_pos hy, lt_tsub_iff_right] at h
221
256
222
- theorem arctan_add {x y : ℝ} (h : x * y < 1 ) :
257
+ theorem arctan_add (h : x * y < 1 ) :
223
258
arctan x + arctan y = arctan ((x + y) / (1 - x * y)) := by
224
259
rw [← arctan_tan (x := _ + _)]
225
260
· congr
@@ -230,7 +265,7 @@ theorem arctan_add {x y : ℝ} (h : x * y < 1) :
230
265
exact arctan_add_arctan_lt_pi_div_two h
231
266
· exact arctan_add_arctan_lt_pi_div_two h
232
267
233
- theorem arctan_add_eq_add_pi {x y : ℝ} (h : 1 < x * y) (hx : 0 < x) :
268
+ theorem arctan_add_eq_add_pi (h : 1 < x * y) (hx : 0 < x) :
234
269
arctan x + arctan y = arctan ((x + y) / (1 - x * y)) + π := by
235
270
have hy : 0 < y := by
236
271
have := mul_pos_iff.mp (zero_lt_one.trans h)
@@ -242,23 +277,23 @@ theorem arctan_add_eq_add_pi {x y : ℝ} (h : 1 < x * y) (hx : 0 < x) :
242
277
field_simp
243
278
rw [show -x + -y = -(x + y) by ring, show x * y - 1 = -(1 - x * y) by ring, neg_div_neg_eq]
244
279
245
- theorem arctan_add_eq_sub_pi {x y : ℝ} (h : 1 < x * y) (hx : x < 0 ) :
280
+ theorem arctan_add_eq_sub_pi (h : 1 < x * y) (hx : x < 0 ) :
246
281
arctan x + arctan y = arctan ((x + y) / (1 - x * y)) - π := by
247
282
rw [← neg_mul_neg] at h
248
283
have k := arctan_add_eq_add_pi h (neg_pos.mpr hx)
249
284
rw [show _ / _ = -((x + y) / (1 - x * y)) by ring, ← neg_inj] at k
250
285
simp only [arctan_neg, neg_add, neg_neg, ← sub_eq_add_neg _ π] at k
251
286
exact k
252
287
253
- theorem two_mul_arctan {x : ℝ} (h₁ : -1 < x) (h₂ : x < 1 ) :
288
+ theorem two_mul_arctan (h₁ : -1 < x) (h₂ : x < 1 ) :
254
289
2 * arctan x = arctan (2 * x / (1 - x ^ 2 )) := by
255
290
rw [two_mul, arctan_add (by nlinarith)]; congr 1 ; ring
256
291
257
- theorem two_mul_arctan_add_pi {x : ℝ} (h : 1 < x) :
292
+ theorem two_mul_arctan_add_pi (h : 1 < x) :
258
293
2 * arctan x = arctan (2 * x / (1 - x ^ 2 )) + π := by
259
294
rw [two_mul, arctan_add_eq_add_pi (by nlinarith) (by linarith)]; congr 2 ; ring
260
295
261
- theorem two_mul_arctan_sub_pi {x : ℝ} (h : x < -1 ) :
296
+ theorem two_mul_arctan_sub_pi (h : x < -1 ) :
262
297
2 * arctan x = arctan (2 * x / (1 - x ^ 2 )) - π := by
263
298
rw [two_mul, arctan_add_eq_sub_pi (by nlinarith) (by linarith)]; congr 2 ; ring
264
299
@@ -278,11 +313,35 @@ theorem four_mul_arctan_inv_5_sub_arctan_inv_239 : 4 * arctan 5⁻¹ - arctan 23
278
313
279
314
end ArctanAdd
280
315
316
+ theorem sin_arctan_strictMono : StrictMono (sin <| arctan ·) := fun x y h ↦
317
+ strictMonoOn_sin (Ioo_subset_Icc_self <| arctan_mem_Ioo x)
318
+ (Ioo_subset_Icc_self <| arctan_mem_Ioo y) (arctan_strictMono h)
319
+
320
+ @[simp]
321
+ theorem sin_arctan_pos : 0 < sin (arctan x) ↔ 0 < x := by
322
+ simpa using sin_arctan_strictMono.lt_iff_lt (a := 0 )
323
+
324
+ @[simp]
325
+ theorem sin_arctan_lt_zero : sin (arctan x) < 0 ↔ x < 0 := by
326
+ simpa using sin_arctan_strictMono.lt_iff_lt (b := 0 )
327
+
328
+ @[simp]
329
+ theorem sin_arctan_eq_zero : sin (arctan x) = 0 ↔ x = 0 :=
330
+ sin_arctan_strictMono.injective.eq_iff' <| by simp
331
+
332
+ @[simp]
333
+ theorem sin_arctan_nonneg : 0 ≤ sin (arctan x) ↔ 0 ≤ x := by
334
+ simpa using sin_arctan_strictMono.le_iff_le (a := 0 )
335
+
336
+ @[simp]
337
+ theorem sin_arctan_le_zero : sin (arctan x) ≤ 0 ↔ x ≤ 0 := by
338
+ simpa using sin_arctan_strictMono.le_iff_le (b := 0 )
339
+
281
340
@[continuity]
282
341
theorem continuous_arctan : Continuous arctan :=
283
342
continuous_subtype_val.comp tanOrderIso.toHomeomorph.continuous_invFun
284
343
285
- theorem continuousAt_arctan {x : ℝ} : ContinuousAt arctan x :=
344
+ theorem continuousAt_arctan : ContinuousAt arctan x :=
286
345
continuous_arctan.continuousAt
287
346
288
347
/-- `Real.tan` as a `PartialHomeomorph` between `(-(π / 2), π / 2)` and the whole line. -/
@@ -309,3 +368,44 @@ theorem coe_tanPartialHomeomorph_symm : ⇑tanPartialHomeomorph.symm = arctan :=
309
368
rfl
310
369
311
370
end Real
371
+
372
+ namespace Mathlib.Meta.Positivity
373
+ open Lean Meta Qq
374
+
375
+ /-- Extension for `Real.arctan`. -/
376
+ @[positivity Real.arctan _]
377
+ def evalRealArctan : PositivityExt where eval {u α} z p e := do
378
+ match u, α, e with
379
+ | 0 , ~q(ℝ), ~q(Real.arctan $a) =>
380
+ let ra ← core z p a
381
+ assumeInstancesCommute
382
+ match ra with
383
+ | .positive pa => return .positive q(Real.arctan_pos.mpr $pa)
384
+ | .nonnegative na => return .nonnegative q(Real.arctan_nonneg.mpr $na)
385
+ | .nonzero na => return .nonzero q(mt Real.arctan_eq_zero_iff.mp $na)
386
+ | .none => return .none
387
+ | _ => throwError "not Real.arctan"
388
+
389
+ /-- Extension for `Real.cos (Real.arctan _)`. -/
390
+ @[positivity Real.cos (Real.arctan _)]
391
+ def evalRealCosArctan : PositivityExt where eval {u α} _ _ e := do
392
+ match u, α, e with
393
+ | 0 , ~q(ℝ), ~q(Real.cos (Real.arctan $a)) =>
394
+ assumeInstancesCommute
395
+ return .positive q(Real.cos_arctan_pos _)
396
+ | _ => throwError "not Real.cos (Real.arctan _)"
397
+
398
+ /-- Extension for `Real.sin (Real.arctan _)`. -/
399
+ @[positivity Real.sin (Real.arctan _)]
400
+ def evalRealSinArctan : PositivityExt where eval {u α} z p e := do
401
+ match u, α, e with
402
+ | 0 , ~q(ℝ), ~q(Real.sin (Real.arctan $a)) =>
403
+ assumeInstancesCommute
404
+ match ← core z p a with
405
+ | .positive pa => return .positive q(Real.sin_arctan_pos.mpr $pa)
406
+ | .nonnegative na => return .nonnegative q(Real.sin_arctan_nonneg.mpr $na)
407
+ | .nonzero na => return .nonzero q(mt Real.sin_arctan_eq_zero.mp $na)
408
+ | .none => return .none
409
+ | _ => throwError "not Real.sin (Real.arctan _)"
410
+
411
+ end Mathlib.Meta.Positivity
0 commit comments