Zulip Chat Archive

Stream: Is there code for X?

Topic: Computation of an explicit sum


Riccardo Brasca (Oct 11 2022 at 14:27):

Working on the flt-project I need to prove something like

import algebra.big_operators.basic
import tactic.linarith

open_locale big_operators

open nat

namespace test

variables {R : Type*} [comm_ring R] {n : } (hn : 4  n)

include hn

def f (a : ) : fin n   := λ x, if x = 1, by linarith then a else
  if x = n.pred, pred_lt (by linarith)⟩ then -a else 0

example (x : R) (a : ) :  (j : fin n), f hn a j  x ^ (j : ) =
  a * x ^ ((⟨1, by linarith : fin n) : ) -
  a * x ^ ((⟨n.pred, pred_lt (by linarith)⟩ : fin n) : ) := sorry

end test

I can do it by hand, but later I will need a similar result with 4 terms, and this is already annoying enough... Does anyone see a smart way of doing it? Note that I don't care about the definition of f, I only need a function f : fin n → ℤ such that the example is true (but I cannot change the RHS).

Floris van Doorn (Oct 11 2022 at 14:33):

Is there a reason you work with fin in the first place, and not sum over docs#finset.range?

Riccardo Brasca (Oct 11 2022 at 14:40):

I think it's irrelevant, f can be defined on and one can use docs#finset.sum_range. In my application I have at some point to use fin because I need to identify the LHS with a linear combination of element of a basis, but I think I can use docs#finset.sum_range also for that.

Riccardo Brasca (Oct 11 2022 at 14:50):

The current proof is

import algebra.big_operators.basic
import tactic.linarith

open_locale big_operators

open nat finset

namespace test

variables {R : Type*} [comm_ring R] {n : } (hn : 4  n)

include hn

def f (a : ) : fin n   := λ x, if x = 1, by linarith then a else
  if x = n.pred, pred_lt (by linarith)⟩ then -a else 0

example (x : R) (a : ) :  (j : fin n), f hn a j  x ^ (j : ) =
  a * x ^ ((⟨1, by linarith : fin n) : ) -
  a * x ^ ((⟨n.pred, pred_lt (by linarith)⟩ : fin n) : ) :=
begin
  have hnotmem : (⟨n.pred, pred_lt (by linarith)⟩ : fin n)  univ.erase (⟨1, by linarith : fin n),
  { refine mem_erase.2 λ h, _, mem_univ _⟩,
    simp only [fin.ext_iff, fin.coe_mk, nat.pred_eq_succ_iff] at h,
    linarith },
  rw [ insert_erase (mem_univ (⟨1, by linarith : fin n)), sum_insert,  insert_erase hnotmem,
    sum_insert],
  suffices :  i  (univ.erase (⟨1, by linarith : fin n)).erase
    (⟨n.pred, pred_lt (by linarith)⟩ : fin n), f hn a i  x ^ (i : ) = 0,
  { rw [sum_congr rfl this, sum_const_zero, add_zero],
    have hn2 : n  2 := λ _, by linarith,
    simp [f, hn2, sub_eq_add_neg] },
  intros i hi,
  suffices H : i  1, by linarith  i  n.pred, pred_lt (by linarith)⟩, simp [H.1, H.2, f],
  exact λ heq, by simpa [heq] using hi,
    λ heq, by simpa [heq] using erase_subset_erase _ (erase_subset _ _) hi⟩,
  repeat { exact not_mem_erase _ _ }
end

end test

That's not that bad, but still...

Riccardo Brasca (Oct 11 2022 at 14:51):

(I can of course remove a lot of linarith, but that's not important)

Floris van Doorn (Oct 11 2022 at 14:54):

import algebra.big_operators.basic

open_locale big_operators

open nat finset

@[simp]
lemma finset.range_filter_eq {n m : } : (range n).filter (= m) = if m < n then {m} else  :=
sorry

lemma ne_and_eq_iff_right {α} {a b c : α} (h : b  c) : a  b  a = c  a = c :=
and_iff_right_of_imp (λ h2, h2.symm  h.symm)

namespace test

variables {R : Type*} [comm_ring R] {n : } (hn : 4  n)

include hn
def f (a : ) :    := λ x, if x = 1 then a else if x = n.pred then -a else 0

example (x : R) (a : ) :  j in range n, f hn a j  x ^ (j : ) = a * x ^ 1 - a * x ^ n.pred :=
begin
  have h2n : 1  n.pred := sorry,
  have h3n : 1 < n := sorry,
  have h4n : n.pred < n := sorry,
  simp_rw [f, ite_smul, sum_ite, finset.filter_filter,  ne.def, ne_and_eq_iff_right h2n,
    finset.range_filter_eq],
  simp [h3n, h4n, sub_eq_add_neg],
end

end test

Floris van Doorn (Oct 11 2022 at 14:58):

This can be repeated with more than 2 terms relatively easily. You just have to show linearly many assumptions i < n and quadratically many assumptions i ≠ j

Riccardo Brasca (Oct 11 2022 at 14:59):

Oooh, very nice!!

Floris van Doorn (Oct 11 2022 at 15:04):

Here is an example with 3 terms:

def f (a : ) :    := λ x, if x = 1 then a else if x = 2 then 1 else if x = n.pred then -a else 0

example (x : R) (a : ) :  j in range n, f hn a j  x ^ (j : ) = a * x ^ 1 + x ^ 2 - a * x ^ n.pred :=
begin
  have h2n : 1  n.pred := sorry,
  have h12 : 1  2 := sorry,
  have h5n : 2  n.pred := sorry,
  have h3n : 1 < n := sorry,
  have h6n : 2 < n := sorry,
  have h4n : n.pred < n := sorry,
  simp [f, ite_smul, sum_ite, finset.filter_filter,  ne.def, and_assoc,
    ne_and_eq_iff_right h12, ne_and_eq_iff_right h5n, ne_and_eq_iff_right h2n,
    finset.range_filter_eq, *, sub_eq_add_neg, add_assoc],
end

Riccardo Brasca (Oct 11 2022 at 15:07):

Let me make sure I can use a function f : ℕ → ℤ, but thanks a lot!

Floris van Doorn (Oct 11 2022 at 15:07):

It should not be too hard to adapt this argument to fin, it will just get a whole lot uglier.


Last updated: Dec 20 2023 at 11:08 UTC