Repository: ivy-llc/ivy

Issue:
negative_binomial



Discussion:

Resolving patch:
diff --git a/ivy/functional/frontends/numpy/random/functions.py b/ivy/functional/frontends/numpy/random/functions.py
--- a/ivy/functional/frontends/numpy/random/functions.py
+++ b/ivy/functional/frontends/numpy/random/functions.py
@@ -117,3 +117,19 @@ def chisquare(df, size=None):
 def lognormal(mean=0.0, sigma=1.0, size=None):
     ret = ivy.exp(ivy.random_normal(mean=mean, std=sigma, shape=size, dtype="float64"))
     return ret
+
+
+@to_ivy_arrays_and_back
+@from_zero_dim_arrays_to_scalar
+def negative_binomial(n, p, size=None):
+    if p <= 0 or p >= 1:
+        raise ValueError("p must be in the interval (0, 1)")
+    if n <= 0:
+        raise ValueError("n must be strictly positive")
+    # numpy implementation uses scale = (1 - p) / p
+    scale = (1 - p) / p
+    # poisson requires shape to be a tuple
+    if isinstance(size, int):
+        size = (size,)
+    lambda_ = ivy.gamma(n, scale, shape=size)
+    return ivy.poisson(lam=lambda_, shape=size)


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_random/test_functions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_random/test_functions.py
--- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_random/test_functions.py
+++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_random/test_functions.py
@@ -451,8 +451,12 @@ def test_numpy_chisquare(
 @handle_frontend_test(
     fn_tree="numpy.random.lognormal",
     input_dtypes=helpers.get_dtypes("float", index=2),
-    mean=st.floats(allow_nan=False, allow_infinity=False, width=32, min_value=-5, max_value=5),
-    sigma=st.floats(allow_nan=False, allow_infinity=False, width=32, min_value=0, max_value=5),
+    mean=st.floats(
+        allow_nan=False, allow_infinity=False, width=32, min_value=-5, max_value=5
+    ),
+    sigma=st.floats(
+        allow_nan=False, allow_infinity=False, width=32, min_value=0, max_value=5
+    ),
     size=st.tuples(
         st.integers(min_value=2, max_value=5), st.integers(min_value=2, max_value=5)
     ),
@@ -478,3 +482,53 @@ def test_numpy_lognormal(
         sigma=sigma,
         size=size,
     )
+
+
+# negative_binomial
+@handle_frontend_test(
+    fn_tree="numpy.random.negative_binomial",
+    input_dtypes=helpers.get_dtypes("float", index=2),
+    # max value for n and min value for p are restricted in testing
+    # as they can blow up poisson lambda, which will cause an
+    # error (lam value too large).
+    n=st.floats(
+        allow_nan=False,
+        allow_infinity=False,
+        width=32,
+        min_value=0,
+        max_value=100000,
+        exclude_min=True,
+    ),
+    p=st.floats(
+        allow_nan=False,
+        allow_infinity=False,
+        width=32,
+        min_value=9.999999747378752e-06,
+        exclude_min=True,
+        max_value=1,
+        exclude_max=True,
+    ),
+    size=helpers.get_shape(allow_none=True),
+    test_with_out=st.just(False),
+)
+def test_numpy_negative_binomial(
+    input_dtypes,
+    size,
+    frontend,
+    test_flags,
+    fn_tree,
+    on_device,
+    n,
+    p,
+):
+    helpers.test_frontend_function(
+        input_dtypes=input_dtypes,
+        frontend=frontend,
+        test_flags=test_flags,
+        fn_tree=fn_tree,
+        on_device=on_device,
+        test_values=False,
+        n=n,
+        p=p,
+        size=size,
+    )