Skip to content

Commit 031ced0

Browse files
Add math functions (#2609)
* Add sumprod(), frexp(), usclose() functions * Add tests Added tests for sumprod(), frexp(), and isclose() functions * fix an error * fix an error * fix an error * fix errors * remove sumprod() * remove empty lines Co-authored-by: Shaikh Ubaid <[email protected]> * Add tests * Update src/runtime/math.py Co-authored-by: Shaikh Ubaid <[email protected]> --------- Co-authored-by: Shaikh Ubaid <[email protected]>
1 parent 118d23e commit 031ced0

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

integration_tests/test_math.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from math import (factorial, isqrt, perm, comb, degrees, radians, exp, pow,
22
ldexp, fabs, gcd, lcm, floor, ceil, remainder, expm1, fmod, log1p, trunc,
3-
modf, fsum, prod, dist)
3+
modf, fsum, prod, dist, frexp, isclose)
44
import math
5-
from lpython import i32, i64, f32, f64
5+
from lpython import i8, i16, i32, i64, f32, f64
66

77
eps: f64
88
eps = 1e-12
@@ -253,6 +253,58 @@ def test_issue_1242():
253253
assert abs(math.pi - 3.14159265358979323846) < 1e-10
254254

255255

256+
def test_frexp():
257+
x:f64 = 6.23
258+
mantissa:f64
259+
exponent:i16
260+
mantissa, exponent = frexp(x)
261+
assert abs(mantissa - 0.77875) < eps and exponent == i16(3)
262+
263+
x = 0.8
264+
mantissa, exponent = frexp(x)
265+
assert abs(mantissa - 0.8) < eps and exponent == i16(0)
266+
267+
x = 19.74
268+
mantissa, exponent = frexp(x)
269+
assert abs(mantissa - 0.616875) < eps and exponent == i16(5)
270+
271+
x = -23.6
272+
mantissa, exponent = frexp(x)
273+
assert abs(mantissa + 0.7375) < eps and exponent == i16(5)
274+
275+
y:f32 = f32(1.23)
276+
mantissa2:f32
277+
exponent2:i8
278+
mantissa2, exponent2 = frexp(y)
279+
assert abs(mantissa2 - f32(0.615)) < f32(eps) and exponent2 == i8(1)
280+
281+
y = f32(-1.23)
282+
mantissa2, exponent2 = frexp(y)
283+
assert abs(mantissa2 - f32(-0.615)) < f32(eps) and exponent2 == i8(1)
284+
285+
286+
def test_isclose():
287+
x:f64 = 2.2130
288+
y:f64 = 2.2129
289+
assert isclose(x, y, rel_tol=0.01, abs_tol=0.001)
290+
assert isclose(x,y,rel_tol=0.0000001,abs_tol=0.01)
291+
assert isclose(x,y,rel_tol=0.1,abs_tol=0.000001)
292+
assert not isclose(x,y,rel_tol=0.0000001,abs_tol=0.00001)
293+
294+
x = -1.265
295+
y = 1.265
296+
assert not isclose(x,y,rel_tol=0.001,abs_tol=0.0001)
297+
assert not isclose(y,x,rel_tol=0.01,abs_tol=0.1)
298+
assert not isclose(x,y,rel_tol=0.01,abs_tol=0.1)
299+
300+
x = -1.2650
301+
y = -1.2651
302+
assert isclose(x, y, rel_tol=0.01, abs_tol=0.001)
303+
assert isclose(x,y,rel_tol=0.0000001,abs_tol=0.01)
304+
assert isclose(x,y,rel_tol=0.1,abs_tol=0.000001)
305+
assert not isclose(x,y,rel_tol=0.0000001,abs_tol=0.00001)
306+
307+
256308
def check():
257309
test_factorial_1()
258310
test_comb()
@@ -278,6 +330,8 @@ def check():
278330
test_dist()
279331
test_modf()
280332
test_issue_1242()
333+
test_frexp()
334+
test_isclose()
281335

282336

283337
check()

src/runtime/math.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,3 +709,39 @@ def remainder(x: f64, y: f64) -> f64:
709709
if x - y*f64(q) > y*f64(q + i64(1)) - x:
710710
return x - y*f64(q + i64(1))
711711
return x - y*f64(q)
712+
713+
714+
@overload
715+
def frexp(x:f64) -> tuple[f64,i16]:
716+
'''
717+
Return the mantissa and exponent of x as the pair (m, e).
718+
m is a float and e is an integer such that x == m * 2**e exactly.
719+
'''
720+
exponent: i16 = i16(0)
721+
while f64(fabs(x)) > f64(1.0):
722+
exponent += i16(1)
723+
x /= 2.0
724+
return x, exponent
725+
726+
727+
@overload
728+
def frexp(x:f32) -> tuple[f32,i8]:
729+
'''
730+
Return the mantissa and exponent of x as the pair (m, e).
731+
m is a float and e is an integer such that x == m * 2**e exactly.
732+
'''
733+
exponent: i8 = i8(0)
734+
while f32(fabs(x)) > f32(1.0):
735+
exponent += i8(1)
736+
x /= f32(2.0)
737+
return x, exponent
738+
739+
740+
@overload
741+
def isclose(a:f64, b:f64, rel_tol:f64 = 1e-09, abs_tol:f64 = 0.0) -> bool:
742+
'''
743+
Return True if the values a and b are close to each other and False otherwise.
744+
'''
745+
difference:f64 = fabs(a-b)
746+
greater:f64 = max(fabs(a),fabs(b))
747+
return difference <= max(rel_tol*greater, abs_tol)

0 commit comments

Comments
 (0)