From b3474b23bbe3aab074b6bd6521764c570f9e2bca Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 04:21:23 +0530 Subject: [PATCH 1/7] Implement `random.random()` --- integration_tests/run_tests.py | 1 + integration_tests/test_random.py | 12 ++++++++++++ src/runtime/impure/lfortran_intrinsics.c | 5 +++++ src/runtime/impure/lfortran_intrinsics.h | 1 + src/runtime/random.py | 8 ++++++++ 5 files changed, 27 insertions(+) create mode 100644 integration_tests/test_random.py create mode 100644 src/runtime/random.py diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py index aa70e4bd27..d144ea8d5a 100755 --- a/integration_tests/run_tests.py +++ b/integration_tests/run_tests.py @@ -16,6 +16,7 @@ "modules_01.py", #"modules_02.py", "test_math.py", + "test_random.py", "test_builtin.py", "test_builtin_abs.py", "test_builtin_bool.py", diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py new file mode 100644 index 0000000000..1b97c1fb42 --- /dev/null +++ b/integration_tests/test_random.py @@ -0,0 +1,12 @@ +from ltypes import f64 +import random + + +def test_random(): + r: f64 + r = random.random() + print(r) + assert r >= 0.0 and r < 1.0 + + +test_random() \ No newline at end of file diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index 8ab63d6961..b1394a9b8b 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -30,6 +30,11 @@ LFORTRAN_API void _lfortran_random_number(int n, double *v) } } +LFORTRAN_API float _lfortran_random_float() +{ + return ((float) rand() / (float) RAND_MAX); +} + LFORTRAN_API void _lfortran_printf(const char* format, ...) { va_list args; diff --git a/src/runtime/impure/lfortran_intrinsics.h b/src/runtime/impure/lfortran_intrinsics.h index a72f7eb1a4..78278de587 100644 --- a/src/runtime/impure/lfortran_intrinsics.h +++ b/src/runtime/impure/lfortran_intrinsics.h @@ -31,6 +31,7 @@ typedef double _Complex double_complex_t; LFORTRAN_API double _lfortran_sum(int n, double *v); LFORTRAN_API void _lfortran_random_number(int n, double *v); +LFORTRAN_API float _lfortran_random_float(); LFORTRAN_API void _lfortran_printf(const char* format, ...); LFORTRAN_API void _lfortran_complex_add(struct _lfortran_complex* a, struct _lfortran_complex* b, struct _lfortran_complex *result); diff --git a/src/runtime/random.py b/src/runtime/random.py new file mode 100644 index 0000000000..db6975fcd3 --- /dev/null +++ b/src/runtime/random.py @@ -0,0 +1,8 @@ +from ltypes import f64, ccall + +def random() -> f64: + return _lfortran_random_float() + +@ccall +def _lfortran_random_float() -> f64: + pass From 91ba961a3f27a141599581026bf8f446ac6f004c Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 04:28:10 +0530 Subject: [PATCH 2/7] Write the test for `random.randint()` --- integration_tests/test_random.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py index 1b97c1fb42..1dab99eab3 100644 --- a/integration_tests/test_random.py +++ b/integration_tests/test_random.py @@ -1,4 +1,4 @@ -from ltypes import f64 +from ltypes import i32, f64 import random @@ -7,6 +7,19 @@ def test_random(): r = random.random() print(r) assert r >= 0.0 and r < 1.0 + r = random.random() + print(r) + assert r >= 0.0 and r < 1.0 +def test_randint(): + ri1: i32 + ri2: i32 + ri1 = random.randint(0, 10) # [0, 10] + print(ri1) + assert ri1 >= 0 and ri1 <= 10 + ri2 = random.randint(-50, 76) # [-50, 76] + print(ri2) + assert ri2 >= -50 and ri2 <= 76 -test_random() \ No newline at end of file +test_random() +test_randint() From 471ee2870006cb70927fbdbac9d592626a4b8bb2 Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 04:39:24 +0530 Subject: [PATCH 3/7] Implement `random.randint` --- src/runtime/impure/lfortran_intrinsics.c | 6 ++++++ src/runtime/impure/lfortran_intrinsics.h | 1 + src/runtime/random.py | 9 ++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index b1394a9b8b..9a35ae4c5e 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -35,6 +35,12 @@ LFORTRAN_API float _lfortran_random_float() return ((float) rand() / (float) RAND_MAX); } +LFORTRAN_API int _lfortran_random_int(int lower, int upper) +{ + int randint = lower + (rand() % (upper - lower + 1)); + return randint; +} + LFORTRAN_API void _lfortran_printf(const char* format, ...) { va_list args; diff --git a/src/runtime/impure/lfortran_intrinsics.h b/src/runtime/impure/lfortran_intrinsics.h index 78278de587..1066046259 100644 --- a/src/runtime/impure/lfortran_intrinsics.h +++ b/src/runtime/impure/lfortran_intrinsics.h @@ -32,6 +32,7 @@ typedef double _Complex double_complex_t; LFORTRAN_API double _lfortran_sum(int n, double *v); LFORTRAN_API void _lfortran_random_number(int n, double *v); LFORTRAN_API float _lfortran_random_float(); +LFORTRAN_API int _lfortran_random_int(int lower, int upper); LFORTRAN_API void _lfortran_printf(const char* format, ...); LFORTRAN_API void _lfortran_complex_add(struct _lfortran_complex* a, struct _lfortran_complex* b, struct _lfortran_complex *result); diff --git a/src/runtime/random.py b/src/runtime/random.py index db6975fcd3..5dd87120fc 100644 --- a/src/runtime/random.py +++ b/src/runtime/random.py @@ -1,4 +1,4 @@ -from ltypes import f64, ccall +from ltypes import i32, f64, ccall def random() -> f64: return _lfortran_random_float() @@ -6,3 +6,10 @@ def random() -> f64: @ccall def _lfortran_random_float() -> f64: pass + +def randint(lower: i32, upper: i32) -> i32: + return _lfortran_random_int(lower, upper) + +@ccall +def _lfortran_random_int(lower: i32, upper: i32) -> i32: + pass From 2ee64d0a7ab65608f0977dbb2990b2cab8cdfda8 Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 04:43:12 +0530 Subject: [PATCH 4/7] Add docstrings --- src/runtime/random.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/runtime/random.py b/src/runtime/random.py index 5dd87120fc..b956eace8e 100644 --- a/src/runtime/random.py +++ b/src/runtime/random.py @@ -1,6 +1,9 @@ from ltypes import i32, f64, ccall def random() -> f64: + """ + Returns a random floating point number in the range [0.0, 1.0) + """ return _lfortran_random_float() @ccall @@ -8,6 +11,9 @@ def _lfortran_random_float() -> f64: pass def randint(lower: i32, upper: i32) -> i32: + """ + Return a random integer N such that `lower <= N <= upper`. + """ return _lfortran_random_int(lower, upper) @ccall From e3b7ec85089fbb4e2fa2413e00a30399cb069868 Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 04:51:01 +0530 Subject: [PATCH 5/7] Implement `random.paretovariate()` --- integration_tests/test_random.py | 8 ++++++++ src/runtime/random.py | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py index 1dab99eab3..2c78bb6d27 100644 --- a/integration_tests/test_random.py +++ b/integration_tests/test_random.py @@ -21,5 +21,13 @@ def test_randint(): print(ri2) assert ri2 >= -50 and ri2 <= 76 +def test_paretovariate(): + r: f64 + r = random.paretovariate(2.0) + print(r) + r = random.paretovariate(-5.6) + print(r) + test_random() test_randint() +test_paretovariate() diff --git a/src/runtime/random.py b/src/runtime/random.py index b956eace8e..a1e5e98239 100644 --- a/src/runtime/random.py +++ b/src/runtime/random.py @@ -1,5 +1,6 @@ from ltypes import i32, f64, ccall + def random() -> f64: """ Returns a random floating point number in the range [0.0, 1.0) @@ -19,3 +20,11 @@ def randint(lower: i32, upper: i32) -> i32: @ccall def _lfortran_random_int(lower: i32, upper: i32) -> i32: pass + +def paretovariate(alpha: f64) -> f64: + """ + Return a random number from a Pareto distribution with parameter `alpha`. + """ + u: f64 + u = 1.0 - random() + return u ** (-1.0 / alpha) From 1875423675d8a6a65ac18ac37fcb8eec51451635 Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 04:59:48 +0530 Subject: [PATCH 6/7] Write the test for `random.randrange()` --- integration_tests/test_random.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py index 2c78bb6d27..2ad5e15a54 100644 --- a/integration_tests/test_random.py +++ b/integration_tests/test_random.py @@ -11,6 +11,15 @@ def test_random(): print(r) assert r >= 0.0 and r < 1.0 +def test_randrange(): + r: i32 + r = random.randrange(0, 10) # [0, 10) + print(r) + assert r >= 0 and r < 10 + r = random.randrange(-50, 76) # [-50, 76) + print(r) + assert r >= -50 and r < 76 + def test_randint(): ri1: i32 ri2: i32 @@ -29,5 +38,6 @@ def test_paretovariate(): print(r) test_random() +test_randrange() test_randint() test_paretovariate() From 66bcf260ef24bc5f075266b0178cf411f895bffb Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Mon, 7 Mar 2022 05:14:01 +0530 Subject: [PATCH 7/7] Implement `random.randrange()` --- src/runtime/impure/lfortran_intrinsics.c | 6 ++++++ src/runtime/impure/lfortran_intrinsics.h | 1 + src/runtime/random.py | 10 ++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index 9a35ae4c5e..c228ebde27 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -35,6 +35,12 @@ LFORTRAN_API float _lfortran_random_float() return ((float) rand() / (float) RAND_MAX); } +LFORTRAN_API int _lfortran_randrange(int lower, int upper) +{ + int rr = lower + (rand() % (upper - lower)); + return rr; +} + LFORTRAN_API int _lfortran_random_int(int lower, int upper) { int randint = lower + (rand() % (upper - lower + 1)); diff --git a/src/runtime/impure/lfortran_intrinsics.h b/src/runtime/impure/lfortran_intrinsics.h index 1066046259..aff7f50664 100644 --- a/src/runtime/impure/lfortran_intrinsics.h +++ b/src/runtime/impure/lfortran_intrinsics.h @@ -32,6 +32,7 @@ typedef double _Complex double_complex_t; LFORTRAN_API double _lfortran_sum(int n, double *v); LFORTRAN_API void _lfortran_random_number(int n, double *v); LFORTRAN_API float _lfortran_random_float(); +LFORTRAN_API int _lfortran_randrange(int lower, int upper); LFORTRAN_API int _lfortran_random_int(int lower, int upper); LFORTRAN_API void _lfortran_printf(const char* format, ...); LFORTRAN_API void _lfortran_complex_add(struct _lfortran_complex* a, diff --git a/src/runtime/random.py b/src/runtime/random.py index a1e5e98239..2b8da20ed4 100644 --- a/src/runtime/random.py +++ b/src/runtime/random.py @@ -11,6 +11,16 @@ def random() -> f64: def _lfortran_random_float() -> f64: pass +def randrange(lower: i32, upper: i32) -> i32: + """ + Return a random integer N such that `lower <= N < upper`. + """ + return _lfortran_randrange(lower, upper) + +@ccall +def _lfortran_randrange(lower: i32, upper: i32) -> i32: + pass + def randint(lower: i32, upper: i32) -> i32: """ Return a random integer N such that `lower <= N <= upper`.