Zulip Chat Archive
Stream: Is there code for X?
Topic: Product of i < j and j < i
Riccardo Brasca (Nov 05 2021 at 13:42):
This was nonsense.
Does someone see a quick way of proving the following?
Alex J. Best (Nov 05 2021 at 13:49):
Is this true as stated? Why can't the set of i larger than a be empty say and the other one not be?
Riccardo Brasca (Nov 05 2021 at 13:50):
Because I am stupid.
Riccardo Brasca (Nov 05 2021 at 13:50):
Time for coffee
Riccardo Brasca (Nov 05 2021 at 14:21):
Ok, the real question is
import data.fin.interval
open_locale big_operators
example {R : Type*} [comm_ring R] {n : ℕ} (f : fin n → R) :
∏ i, (∏ j in finset.univ.filter (λ j, j < i), (f j - f i) * (f i - f j)) =
∏ i, (∏ j in finset.univ.filter (λ j, i ≠ j), (f j - f i)) := sorry
I am not asking to do my work, but suggestions are welcome :)
Eric Wieser (Nov 05 2021 at 14:24):
I think the RHS is ∏ i in (finset.univ : finset ℕ).off_diag, f i.2 - f i.1
?
Yaël Dillies (Nov 05 2021 at 14:27):
You can move multiplication out of the LHS, swap the products on the right factor, then split the prod on the RHS as the i < j
and j < i
bits.
Eric Wieser (Nov 05 2021 at 14:29):
Do we have something like docs#finset.filter_or
Riccardo Brasca (Nov 05 2021 at 14:29):
It's the "swap the product" part that is causing me troubles.
Riccardo Brasca (Nov 05 2021 at 14:30):
Ah, docs#finset.filter_or seems relevant
Eric Wieser (Nov 05 2021 at 14:35):
Yeah, simp_rw [ne_iff_lt_or_gt, finset.filter_or],
is a good start
Yaël Dillies (Nov 05 2021 at 14:36):
You might need to turn the double sum in a single one using docs#finset.product and docs#finset.prod_product.
Yaël Dillies (Nov 05 2021 at 14:37):
And once again Eric, finset.prod_product_right
would come in handy!
Eric Wieser (Nov 05 2021 at 14:39):
Well, no more handy than rw [prod_product, prod_comm]
Eric Wieser (Nov 05 2021 at 14:48):
This gets through some of the pain:
example {R : Type*} [comm_ring R] {n : ℕ} (f : fin n → R) :
∏ i, (∏ j in finset.univ.filter (λ j, j < i), (f j - f i) * (f i - f j)) =
∏ i, (∏ j in finset.univ.filter (λ j, i ≠ j), (f j - f i)) :=
begin
simp_rw [ne_iff_lt_or_gt, finset.filter_or],
refine eq.trans _ (congr_arg (finset.prod _) (funext $ λ i, (finset.prod_union _).symm)),
simp_rw [finset.prod_mul_distrib],
sorry,
{ rintro x hx,
obtain ⟨⟨_, hl⟩, ⟨_, hg⟩⟩ := (finset.mem_inter.1 hx).imp finset.mem_filter.1 finset.mem_filter.1,
exact (lt_asymm hl hg).elim, },
end
Riccardo Brasca (Nov 05 2021 at 15:48):
example {R : Type*} [comm_ring R] {n : ℕ} (f : fin n → R) :
∏ i, (∏ j in finset.univ.filter (λ j, j < i), (f j - f i) * (f i - f j)) =
∏ i, (∏ j in finset.univ.filter (λ j, i ≠ j), (f j - f i)) :=
begin
simp_rw [ne_iff_lt_or_gt, finset.filter_or],
refine eq.trans _ (congr_arg (finset.prod _) (funext $ λ i, (finset.prod_union _).symm)),
simp_rw [finset.prod_mul_distrib],
{ conv_rhs {
congr, skip, congr, skip, funext,
conv {
congr, skip, funext,
rw [← neg_sub, neg_eq_neg_one_mul] },
rw [finset.prod_mul_distrib, finset.prod_const], },
simp_rw [finset.prod_mul_distrib],
rw [← mul_assoc],
congr,
sorry,
},
{ rintro x hx,
obtain ⟨⟨_, hl⟩, ⟨_, hg⟩⟩ := (finset.mem_inter.1 hx).imp finset.mem_filter.1 finset.mem_filter.1,
exact (lt_asymm hl hg).elim, },
end
Takes care of one half of the product, the easy part...
Riccardo Brasca (Nov 05 2021 at 16:34):
And let's simp
for the win.
lemma prod_filter_lt_mul_neg_eq_prod_off_diag {R : Type*} [comm_ring R] {n : ℕ} (f : fin n → R) :
∏ i, (∏ j in finset.univ.filter (λ j, j < i), (f j - f i) * (f i - f j)) =
∏ i, (∏ j in finset.univ.filter (λ j, i ≠ j), (f j - f i)) :=
begin
simp_rw [ne_iff_lt_or_gt, finset.filter_or],
refine eq.trans _ (congr_arg (finset.prod _) (funext $ λ i, (finset.prod_union _).symm)),
simp_rw [finset.prod_mul_distrib],
{ conv_rhs {
congr, skip, congr, skip, funext,
conv {
congr, skip, funext,
rw [← neg_sub, neg_eq_neg_one_mul] },
rw [finset.prod_mul_distrib, finset.prod_const] },
simp_rw [finset.prod_mul_distrib],
rw [← mul_assoc],
congr,
conv_lhs {
congr, skip, funext,
conv {
congr, skip, funext,
rw [← neg_sub, neg_eq_neg_one_mul] },
rw [finset.prod_mul_distrib, finset.prod_const] },
simp_rw [finset.prod_mul_distrib, filter_gt_card],
nth_rewrite 0 [mul_comm],
congr' 1,
rw [finset.prod_sigma', finset.prod_sigma'],
exact finset.prod_bij' (λ i hi, ⟨i.2, i.1⟩) (by simp) (by simp) (λ i hi, ⟨i.2, i.1⟩)
(by simp) (by simp) (by simp) },
{ rintro x hx,
obtain ⟨⟨_, hl⟩, ⟨_, hg⟩⟩ := (finset.mem_inter.1 hx).imp finset.mem_filter.1 finset.mem_filter.1,
exact (lt_asymm hl hg).elim, },
end
Eric Wieser (Nov 05 2021 at 16:53):
Does this lemma generalize to g i j = f i - f j
?
Floris van Doorn (Nov 05 2021 at 17:11):
Probably, as long as g i j = - g j i
.
Floris van Doorn (Nov 05 2021 at 17:12):
Oh, or maybe that condition is not even needed
Floris van Doorn (Nov 05 2021 at 17:14):
It can probably be further generalized by replacing ...
edit: nevermind
Riccardo Brasca (Nov 05 2021 at 17:16):
Yes, it should be generalized and golfed
Last updated: Dec 20 2023 at 11:08 UTC