Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ab5e81c

Browse files
authoredMar 25, 2022
Merge pull request #409 from postmath/issue408
Positive * pos_inf should be pos_inf, not 0 +- inf. Same for other combinations of signs.
2 parents 076249e + a9f8822 commit ab5e81c

File tree

8 files changed

+422
-27
lines changed

8 files changed

+422
-27
lines changed
 

‎arb/addmul.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ arb_addmul_arf(arb_t z, const arb_t x, const arf_t y, slong prec)
3333
if (inexact)
3434
arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);
3535
}
36+
else if (arf_is_inf(y) && arb_is_nonzero(x))
37+
{
38+
if (arf_sgn(arb_midref(x)) > 0)
39+
arb_add_arf(z, z, y, prec);
40+
else
41+
arb_sub_arf(z, z, y, prec);
42+
}
3643
else
3744
{
3845
mag_init_set_arf(ym, y);
@@ -78,6 +85,20 @@ arb_addmul(arb_t z, const arb_t x, const arb_t y, slong prec)
7885

7986
*arb_radref(z) = *zr;
8087
}
88+
else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)) && arb_is_nonzero(y))
89+
{
90+
if (arf_sgn(arb_midref(y)) > 0)
91+
arb_add_arf(z, z, arb_midref(x), prec);
92+
else
93+
arb_sub_arf(z, z, arb_midref(x), prec);
94+
}
95+
else if (arf_is_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)) && arb_is_nonzero(x))
96+
{
97+
if (arf_sgn(arb_midref(x)) > 0)
98+
arb_add_arf(z, z, arb_midref(y), prec);
99+
else
100+
arb_sub_arf(z, z, arb_midref(y), prec);
101+
}
81102
else
82103
{
83104
mag_init_set_arf(xm, arb_midref(x));

‎arb/fma.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ arb_fma_arf(arb_t res, const arb_t x, const arf_t y, const arb_t z, slong prec)
3939
if (inexact)
4040
arf_mag_fast_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec);
4141
}
42+
else if (arf_is_inf(y) && arb_is_nonzero(x))
43+
{
44+
if (arf_sgn(arb_midref(x)) > 0)
45+
arb_add_arf(res, z, y, prec);
46+
else
47+
arb_sub_arf(res, z, y, prec);
48+
}
4249
else
4350
{
4451
mag_t tm;
@@ -91,6 +98,20 @@ arb_fma(arb_t res, const arb_t x, const arb_t y, const arb_t z, slong prec)
9198

9299
*arb_radref(res) = *zr;
93100
}
101+
else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)) && arb_is_nonzero(y))
102+
{
103+
if (arf_sgn(arb_midref(y)) > 0)
104+
arb_add_arf(res, z, arb_midref(x), prec);
105+
else
106+
arb_sub_arf(res, z, arb_midref(x), prec);
107+
}
108+
else if (arf_is_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)) && arb_is_nonzero(x))
109+
{
110+
if (arf_sgn(arb_midref(x)) > 0)
111+
arb_add_arf(res, z, arb_midref(y), prec);
112+
else
113+
arb_sub_arf(res, z, arb_midref(y), prec);
114+
}
94115
else
95116
{
96117
mag_init_set_arf(xm, arb_midref(x));

‎arb/mul.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ arb_mul_arf(arb_t z, const arb_t x, const arf_t y, slong prec)
4040

4141
*arb_radref(z) = *zr;
4242
}
43+
else if (arf_is_inf(y) && arb_is_nonzero(x))
44+
{
45+
mag_zero(arb_radref(z));
46+
47+
if (arf_sgn(arb_midref(x)) * arf_sgn(y) > 0)
48+
arf_pos_inf(arb_midref(z));
49+
else
50+
arf_neg_inf(arb_midref(z));
51+
}
4352
else
4453
{
4554
mag_init_set_arf(ym, y);
@@ -91,6 +100,16 @@ arb_mul(arb_t z, const arb_t x, const arb_t y, slong prec)
91100

92101
*arb_radref(z) = *zr;
93102
}
103+
else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)) && arb_is_nonzero(y) ||
104+
arf_is_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)) && arb_is_nonzero(x))
105+
{
106+
mag_zero(arb_radref(z));
107+
108+
if (arf_sgn(arb_midref(x)) * arf_sgn(arb_midref(y)) > 0)
109+
arf_pos_inf(arb_midref(z));
110+
else
111+
arf_neg_inf(arb_midref(z));
112+
}
94113
else
95114
{
96115
mag_init_set_arf(xm, arb_midref(x));

‎arb/submul.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ arb_submul_arf(arb_t z, const arb_t x, const arf_t y, slong prec)
3333
if (inexact)
3434
arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);
3535
}
36+
else if (arf_is_inf(y) && arb_is_nonzero(x))
37+
{
38+
if (arf_sgn(arb_midref(x)) > 0)
39+
arb_sub_arf(z, z, y, prec);
40+
else
41+
arb_add_arf(z, z, y, prec);
42+
}
3643
else
3744
{
3845
mag_init_set_arf(ym, y);
@@ -78,6 +85,20 @@ arb_submul(arb_t z, const arb_t x, const arb_t y, slong prec)
7885

7986
*arb_radref(z) = *zr;
8087
}
88+
else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)) && arb_is_nonzero(y))
89+
{
90+
if (arf_sgn(arb_midref(y)) > 0)
91+
arb_sub_arf(z, z, arb_midref(x), prec);
92+
else
93+
arb_add_arf(z, z, arb_midref(x), prec);
94+
}
95+
else if (arf_is_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)) && arb_is_nonzero(x))
96+
{
97+
if (arf_sgn(arb_midref(x)) > 0)
98+
arb_sub_arf(z, z, arb_midref(y), prec);
99+
else
100+
arb_add_arf(z, z, arb_midref(y), prec);
101+
}
81102
else
82103
{
83104
mag_init_set_arf(xm, arb_midref(x));

‎arb/test/t-addmul.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ mag_close(const mag_t am, const mag_t bm)
3939
return res1 && res2;
4040
}
4141

42+
int
43+
arb_equal_mid_close_mag(const arb_t a, const arb_t b)
44+
{
45+
return arf_equal(arb_midref(a), arb_midref(b)) &&
46+
(mag_close(arb_radref(a), arb_radref(b)) ||
47+
/* If a's and b's centres are infinite but their radii are finite, the radii don't need
48+
to be close: they represent signed infinity regardless. If their centres are NaN,
49+
then we should ignore their radii. */
50+
(arf_is_inf(arb_midref(a)) && arf_is_inf(arb_midref(b)) &&
51+
mag_is_finite(arb_radref(a)) && mag_is_finite(arb_radref(b))) ||
52+
(arf_is_nan(arb_midref(a)) && arf_is_nan(arb_midref(b))));
53+
}
54+
4255
void
4356
arb_addmul_naive(arb_t z, const arb_t x, const arb_t y, slong prec)
4457
{
@@ -214,8 +227,7 @@ int main()
214227
arb_addmul(z, x, y, prec);
215228
arb_addmul_naive(v, x, y, prec);
216229

217-
if (!arf_equal(arb_midref(z), arb_midref(v))
218-
|| !mag_close(arb_radref(z), arb_radref(v)))
230+
if (!arb_equal_mid_close_mag(z, v))
219231
{
220232
flint_printf("FAIL!\n");
221233
flint_printf("x = "); arb_print(x); flint_printf("\n\n");
@@ -232,8 +244,7 @@ int main()
232244
arb_addmul(z, x, y, prec);
233245
arb_addmul(v, x, x, prec);
234246

235-
if (!arf_equal(arb_midref(z), arb_midref(v))
236-
|| !mag_close(arb_radref(z), arb_radref(v)))
247+
if (!arb_equal_mid_close_mag(z, v))
237248
{
238249
flint_printf("FAIL (aliasing 1)!\n");
239250
flint_printf("x = "); arb_print(x); flint_printf("\n\n");
@@ -248,8 +259,7 @@ int main()
248259
arb_addmul(v, x, x, prec);
249260
arb_addmul(x, x, x, prec);
250261

251-
if (!arf_equal(arb_midref(x), arb_midref(v))
252-
|| !mag_close(arb_radref(x), arb_radref(v)))
262+
if (!arb_equal_mid_close_mag(x, v))
253263
{
254264
flint_printf("FAIL (aliasing 2)!\n");
255265
flint_printf("x = "); arb_print(x); flint_printf("\n\n");
@@ -263,8 +273,7 @@ int main()
263273
arb_addmul(v, x, y, prec);
264274
arb_addmul(x, x, y, prec);
265275

266-
if (!arf_equal(arb_midref(x), arb_midref(v))
267-
|| !mag_close(arb_radref(x), arb_radref(v)))
276+
if (!arb_equal_mid_close_mag(x, v))
268277
{
269278
flint_printf("FAIL (aliasing 3)!\n");
270279
flint_printf("x = "); arb_print(x); flint_printf("\n\n");
@@ -279,8 +288,7 @@ int main()
279288
arb_addmul(v, x, y, prec);
280289
arb_addmul(x, y, x, prec);
281290

282-
if (!arf_equal(arb_midref(x), arb_midref(v))
283-
|| !mag_close(arb_radref(x), arb_radref(v)))
291+
if (!arb_equal_mid_close_mag(x, v))
284292
{
285293
flint_printf("FAIL (aliasing 4)!\n");
286294
flint_printf("x = "); arb_print(x); flint_printf("\n\n");

‎arb/test/t-mul.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ mag_close(const mag_t am, const mag_t bm)
3939
return res1 && res2;
4040
}
4141

42+
int
43+
arb_equal_mid_close_mag(const arb_t a, const arb_t b)
44+
{
45+
return arf_equal(arb_midref(a), arb_midref(b)) &&
46+
(mag_close(arb_radref(a), arb_radref(b)) ||
47+
/* If a's and b's centres are infinite but their radii are finite, the radii don't need
48+
to be close: they represent signed infinity regardless. If their centres are NaN,
49+
then we should ignore their radii. */
50+
(arf_is_inf(arb_midref(a)) && arf_is_inf(arb_midref(b)) &&
51+
mag_is_finite(arb_radref(a)) && mag_is_finite(arb_radref(b))) ||
52+
(arf_is_nan(arb_midref(a)) && arf_is_nan(arb_midref(b))));
53+
}
54+
4255
void
4356
arb_mul_naive(arb_t z, const arb_t x, const arb_t y, slong prec)
4457
{
@@ -73,15 +86,18 @@ arb_mul_naive(arb_t z, const arb_t x, const arb_t y, slong prec)
7386
fmpz_clear(e);
7487
}
7588

76-
/* propagated error */
77-
if (!arb_is_exact(x))
89+
/* propagated error - note that (signed infinity) * nonzero should be a signed
90+
infinity, meaning the error should *not* propagate */
91+
if (!arb_is_exact(x) && !(
92+
arb_is_nonzero(x) && arf_is_inf(arb_midref(y)) && mag_is_finite(arb_radref(y))))
7893
{
7994
arf_set_mag(t, arb_radref(x));
8095
arf_abs(u, arb_midref(y));
8196
arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP);
8297
}
8398

84-
if (!arb_is_exact(y))
99+
if (!arb_is_exact(y) && !(
100+
arb_is_nonzero(y) && arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))))
85101
{
86102
arf_set_mag(t, arb_radref(y));
87103
arf_abs(u, arb_midref(x));
@@ -265,8 +281,7 @@ int main()
265281
arb_mul(z, x, y, prec);
266282
arb_mul_naive(v, x, y, prec);
267283

268-
if (!arf_equal(arb_midref(z), arb_midref(v))
269-
|| !mag_close(arb_radref(z), arb_radref(v)))
284+
if (!arb_equal_mid_close_mag(z, v))
270285
{
271286
flint_printf("FAIL!\n");
272287
flint_printf("x = "); arb_print(x); flint_printf("\n\n");
@@ -282,8 +297,7 @@ int main()
282297
arb_mul(z, x, y, prec);
283298
arb_mul(v, x, x, prec);
284299

285-
if (!arf_equal(arb_midref(z), arb_midref(v))
286-
|| !mag_close(arb_radref(z), arb_radref(v)))
300+
if (!arb_equal_mid_close_mag(z, v))
287301
{
288302
flint_printf("FAIL (aliasing 1)!\n");
289303
flint_printf("x = "); arb_print(x); flint_printf("\n\n");

0 commit comments

Comments
 (0)