(**
This file is part of the Flocq formalization of floating-point
arithmetic in Coq: http://flocq.gforge.inria.fr/
Copyright (C) 2010-2018 Sylvie Boldo
#<br />#
Copyright (C) 2010-2018 Guillaume Melquiond
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
COPYING file for more details.
*)
(** * Error of the multiplication is in the FLX/FLT format *)
Require Import Core Operations Plus_error. Section Fprop_mult_error. Variable beta : radix. Notation bpow e := (bpow beta e). Variable prec : Z. Context { prec_gt_0_ : Prec_gt_0 prec }. Notation format := (generic_format beta (FLX_exp prec)). Notation cexp := (cexp beta (FLX_exp prec)). Variable rnd : R -> Z. Context { valid_rnd : Valid_rnd rnd }.
Proof. Admitted.
Proof with auto with typeclass_instances. intros x y Hx Hy Hz. set (f := (round beta (FLX_exp prec) rnd (x * y))). destruct (Req_dec (x * y) 0) as [Hxy0|Hxy0]. contradict Hz. rewrite Hxy0. rewrite round_0... ring. destruct (mag beta (x * y)) as (exy, Hexy). specialize (Hexy Hxy0). destruct (mag beta (f - x * y)) as (er, Her). specialize (Her Hz). destruct (mag beta x) as (ex, Hex). assert (Hx0: (x <> 0)%R). contradict Hxy0. now rewrite Hxy0, Rmult_0_l. specialize (Hex Hx0). destruct (mag beta y) as (ey, Hey). assert (Hy0: (y <> 0)%R). contradict Hxy0. now rewrite Hxy0, Rmult_0_r. specialize (Hey Hy0). (* *)
assert (Hc1: (cexp (x * y)%R - prec <= cexp x + cexp y)%Z). unfold cexp, FLX_exp. rewrite mag_unique with (1 := Hex). rewrite mag_unique with (1 := Hey). rewrite mag_unique with (1 := Hexy). cut (exy - 1 < ex + ey)%Z. omega. apply (lt_bpow beta). apply Rle_lt_trans with (1 := proj1 Hexy). rewrite Rabs_mult. rewrite bpow_plus. apply Rmult_le_0_lt_compat. apply Rabs_pos. apply Rabs_pos. apply Hex. apply Hey. (* *)
assert (Hc2: (cexp x + cexp y <= cexp (x * y)%R)%Z). unfold cexp, FLX_exp. rewrite mag_unique with (1 := Hex). rewrite mag_unique with (1 := Hey). rewrite mag_unique with (1 := Hexy). cut ((ex - 1) + (ey - 1) < exy)%Z. generalize (prec_gt_0 prec). clear ; omega. apply (lt_bpow beta). apply Rle_lt_trans with (2 := proj2 Hexy). rewrite Rabs_mult. rewrite bpow_plus. apply Rmult_le_compat. apply bpow_ge_0. apply bpow_ge_0. apply Hex. apply Hey. (* *)
assert (Hr: ((F2R (Float beta (- (Ztrunc (scaled_mantissa beta (FLX_exp prec) x) *
Ztrunc (scaled_mantissa beta (FLX_exp prec) y)) + rnd (scaled_mantissa beta (FLX_exp prec) (x * y)) *
beta ^ (cexp (x * y)%R - (cexp x + cexp y))) (cexp x + cexp y))) = f - x * y)%R). rewrite Hx at 6. rewrite Hy at 6. rewrite <- F2R_mult. simpl. unfold f, round, Rminus. rewrite <- F2R_opp, Rplus_comm, <- F2R_plus. unfold Fplus. simpl. now rewrite Zle_imp_le_bool with (1 := Hc2). (* *)
exists (Float beta (- (Ztrunc (scaled_mantissa beta (FLX_exp prec) x) *
Ztrunc (scaled_mantissa beta (FLX_exp prec) y)) + rnd (scaled_mantissa beta (FLX_exp prec) (x * y)) *
beta ^ (cexp (x * y)%R - (cexp x + cexp y))) (cexp x + cexp y)). split;[assumption|split]. rewrite Hr. simpl. clear Hr. apply Z.le_trans with (cexp (x * y)%R - prec)%Z. unfold cexp, FLX_exp. apply Zplus_le_compat_r. rewrite mag_unique with (1 := Hexy). apply mag_le_bpow with (1 := Hz). replace (bpow (exy - prec)) with (ulp beta (FLX_exp prec) (x * y)). apply error_lt_ulp... rewrite ulp_neq_0; trivial. unfold cexp. now rewrite mag_unique with (1 := Hexy). apply Hc1. reflexivity. Qed.
Proof. Admitted.
Proof. intros x y Hx Hy. destruct (Req_dec (round beta (FLX_exp prec) rnd (x * y) - x * y) 0) as [Hr0|Hr0]. { rewrite Hr0. apply generic_format_0. } { destruct (mult_error_FLX_aux x y Hx Hy Hr0) as ((m,e),(H1,(H2,H3))). rewrite <- H1. apply generic_format_F2R. easy. } Qed.
Proof. Admitted.
Proof. intros x e Fx. destruct (Req_dec x 0) as [Zx|Nzx]. { rewrite Zx. rewrite Rmult_0_l. apply generic_format_0. } { rewrite Fx. set (mx := Ztrunc _). set (ex := cexp _). pose (f := {| Fnum := mx; Fexp := ex + e |} : float beta). apply (generic_format_F2R' _ _ _ f). { unfold F2R. simpl. rewrite bpow_plus. rewrite Rmult_assoc. easy. } { intro Nzmx. unfold mx. unfold ex. rewrite <- Fx. unfold f. unfold ex. simpl. unfold cexp. rewrite (mag_mult_bpow _ _ _ Nzx). unfold FLX_exp. omega. } } Qed.
End Fprop_mult_error. Section Fprop_mult_error_FLT. Variable beta : radix. Notation bpow e := (bpow beta e). Variable emin prec : Z. Context { prec_gt_0_ : Prec_gt_0 prec }. Notation format := (generic_format beta (FLT_exp emin prec)). Notation cexp := (cexp beta (FLT_exp emin prec)). Variable rnd : R -> Z. Context { valid_rnd : Valid_rnd rnd }.
Proof. Admitted.
Proof with auto with typeclass_instances. intros x y Hx Hy Hxy. set (f := (round beta (FLT_exp emin prec) rnd (x * y))). destruct (Req_dec (f - x * y) 0) as [Hr0|Hr0]. rewrite Hr0. apply generic_format_0. destruct (Req_dec (x * y) 0) as [Hxy'|Hxy']. unfold f. rewrite Hxy'. rewrite round_0... ring_simplify (0 - 0)%R. apply generic_format_0. specialize (Hxy Hxy'). destruct (mult_error_FLX_aux beta prec rnd x y) as ((m,e),(H1,(H2,H3))). now apply generic_format_FLX_FLT with emin. now apply generic_format_FLX_FLT with emin. rewrite <- (round_FLT_FLX beta emin). assumption. apply Rle_trans with (2:=Hxy). apply bpow_le. generalize (prec_gt_0 prec). clear ; omega. rewrite <- (round_FLT_FLX beta emin) in H1. 2:apply Rle_trans with (2:=Hxy). 2:apply bpow_le ; generalize (prec_gt_0 prec) ; clear ; omega. unfold f; rewrite <- H1. apply generic_format_F2R. intros _. simpl in H2, H3. unfold cexp, FLT_exp. case (Zmax_spec (mag beta (F2R (Float beta m e)) - prec) emin);
intros (M1,M2); rewrite M2. apply Z.le_trans with (2:=H2). unfold cexp, FLX_exp. apply Z.le_refl. rewrite H3. unfold cexp, FLX_exp. assert (Hxy0:(x*y <> 0)%R). contradict Hr0. unfold f. rewrite Hr0. rewrite round_0... ring. assert (Hx0: (x <> 0)%R). contradict Hxy0. now rewrite Hxy0, Rmult_0_l. assert (Hy0: (y <> 0)%R). contradict Hxy0. now rewrite Hxy0, Rmult_0_r. destruct (mag beta x) as (ex,Ex) ; simpl. specialize (Ex Hx0). destruct (mag beta y) as (ey,Ey) ; simpl. specialize (Ey Hy0). assert (emin + 2 * prec -1 < ex + ey)%Z. 2: omega. apply (lt_bpow beta). apply Rle_lt_trans with (1:=Hxy). rewrite Rabs_mult, bpow_plus. apply Rmult_le_0_lt_compat; try apply Rabs_pos. apply Ex. apply Ey. Qed.