diff options
author | Jade Philipoom <jadep@google.com> | 2018-04-06 12:50:04 +0200 |
---|---|---|
committer | jadephilipoom <jade.philipoom@gmail.com> | 2018-04-11 03:56:21 -0400 |
commit | cf0d84fea542257e342c47e5046c1237a8c8203a (patch) | |
tree | 911c9e859d02b7bcbab99276e356cee3ae8eb6e3 /src/Arithmetic | |
parent | ccc79730a7585a3ce952c27d347b194562f4f473 (diff) |
prove stronger bound on quotient error for barrett reduction
Diffstat (limited to 'src/Arithmetic')
-rw-r--r-- | src/Arithmetic/BarrettReduction/Generalized.v | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/src/Arithmetic/BarrettReduction/Generalized.v b/src/Arithmetic/BarrettReduction/Generalized.v index 76058463c..b24604c3c 100644 --- a/src/Arithmetic/BarrettReduction/Generalized.v +++ b/src/Arithmetic/BarrettReduction/Generalized.v @@ -136,5 +136,97 @@ Section barrett. { symmetry; apply (Zmod_unique a n (q + 1)); subst r; lia. } { symmetry; apply (Zmod_unique a n (q + 2)); subst r; lia. } Qed. + + Section StrongerBounds. + Context (n_good : b ^ offset * (b^(2*k) mod n) <= b ^ (k+offset) - m) (a_good : a < n * b ^ k). + + Lemma helper_1 : b ^ (2 * k) * ((a / n) - 1) <= m * (n * (a / n) - b ^ (k - offset)). + Proof. + autorewrite with push_Zmul. ring_simplify. + replace (a / n * m * n) with (m * n * (a / n)) by ring. + assert (a/n < b ^ k) by auto using Z.div_lt_upper_bound with zarith. + assert (b ^ (2 * k) - m * n = b ^ (2 * k) mod n) by (subst m; rewrite Z.mul_div_eq'; auto with zarith). + assert (0 < b ^ (k - offset)) by auto with zarith. + assert (b ^ (2*k) = b ^ (k - offset) * b ^ (k + offset)) by (rewrite <-Z.pow_add_r; auto with zarith). + pose proof (Z.mod_pos_bound (b ^ (2*k)) n ltac:(lia)). + match goal with |- ?x * (a/n) - ?c <= ?d * (a/n) - ?e => + assert ((b ^ k) * (x - d) <= c - e); [|nia] end. + replace (b ^ k) with (b ^ (k - offset) * b ^ offset) by (rewrite <-Z.pow_add_r; auto with zarith). + nia. + Qed. + + Lemma helper_2 : n * (a / n) - b ^ (k - offset) < b ^ (k - offset) * (a / b ^ (k - offset)). + Proof. + rewrite !Z.mul_div_eq by auto using Z.lt_gt with zarith. + pose proof (Z.mod_pos_bound a n ltac:(omega)). + pose proof (Z.mod_pos_bound a (b ^ (k - offset)) ltac:(auto with zarith)). + lia. + Qed. + + Let epsilon := (a / n) * b ^ (k+offset) - (a / b ^ (k - offset)) * m. + + Lemma q_epsilon : q = (a / n) + (- epsilon) / b ^ (k + offset). + Proof. + subst q. subst epsilon. + rewrite Z.opp_sub_distr. + rewrite <-Z.mul_opp_l. + rewrite Z.div_add_l by auto with zarith. + ring_simplify. f_equal; ring. + Qed. + + Lemma epsilon_lower : - b ^ (k + offset) < epsilon. + Proof. + pose proof q_epsilon as Hq_epsilon. + rewrite (proj2_sig q_nice) in Hq_epsilon. + apply Z.opp_lt_mono. rewrite Z.opp_involutive. + apply Z.div_le_zero; auto with zarith. + destruct (proj1_sig q_nice) as [ [|] [|]]; cbn [fst snd] in *; omega. + Qed. + + Lemma m_pos : 0 < m. + Proof. + subst m. Z.zero_bounds. + split; auto with zarith. + transitivity (b ^ k); auto with zarith. + Qed. + + Lemma epsilon_bound : epsilon < b ^ (k + offset). + Proof. + subst epsilon. pose proof helper_1. pose proof helper_2. pose proof m_pos. + replace (b ^ (2 * k)) with (b^(k - offset) * b ^ (k + offset)) in * + by (rewrite <-Z.pow_add_r; auto with zarith). + apply Z.mul_lt_mono_pos_l with (p:=b^(k-offset)); auto with zarith. + nia. + Qed. + + Lemma q_nice_strong : { b : bool | q = a / n + if b then -1 else 0}. + Proof. + exists (0 <? epsilon). + rewrite q_epsilon. + apply Z.add_cancel_l. + pose proof epsilon_bound. pose proof epsilon_lower. + break_match; Z.ltb_to_lt. + { rewrite Z.div_opp_l_complete by auto with zarith. + rewrite Z.div_small, Z.mod_small by auto with zarith. + break_match; omega. } + { rewrite Z.div_small; auto with zarith. } + Qed. + + Lemma q_bound : a / n - 1 <= q. + Proof. + rewrite (proj2_sig q_nice_strong). + break_match; omega. + Qed. + + Lemma r_small_strong : r < 2 * n. + Proof. + Hint Rewrite (Z.mul_div_eq' a n) using lia : zstrip_div. + assert (a mod n < n) by auto with zarith lia. + unfold r. + apply Z.le_lt_trans with (m:= a - (a / n - 1) * n); [pose proof q_bound; nia | ]. + autorewrite with push_Zmul zsimplify zstrip_div. + auto with lia. + Qed. + End StrongerBounds. End barrett_algorithm. -End barrett. +End barrett.
\ No newline at end of file |