summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaspar Thommen <49198627+kasparthommen@users.noreply.github.com>2020-06-10 22:50:43 +0200
committerGitHub <noreply@github.com>2020-06-10 23:50:43 +0300
commit0ac02d3819157a9c64b78157428336200632cff8 (patch)
tree9a834e03fc3a1819166d499da044efc8dd69a58e
parentd0928f871ccb42484c7e03c456ce489dea908313 (diff)
downloadnumpy-0ac02d3819157a9c64b78157428336200632cff8.tar.gz
BUG: endpoints of array returned by geomspace() should match arguments (#16411)
* BUG: make sure the endpoints of the array returned by geomspace() matches the 'start' and 'stop' arguments exactly Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
-rw-r--r--numpy/core/function_base.py14
-rw-r--r--numpy/core/tests/test_function_base.py36
2 files changed, 47 insertions, 3 deletions
diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py
index 9e46f0ea5..946e255c1 100644
--- a/numpy/core/function_base.py
+++ b/numpy/core/function_base.py
@@ -408,8 +408,18 @@ def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
log_start = _nx.log10(start)
log_stop = _nx.log10(stop)
- result = out_sign * logspace(log_start, log_stop, num=num,
- endpoint=endpoint, base=10.0, dtype=dtype)
+ result = logspace(log_start, log_stop, num=num,
+ endpoint=endpoint, base=10.0, dtype=dtype)
+
+ # Make sure the endpoints match the start and stop arguments. This is
+ # necessary because np.exp(np.log(x)) is not necessarily equal to x.
+ if num > 0:
+ result[0] = start
+ if num > 1 and endpoint:
+ result[-1] = stop
+
+ result = out_sign * result
+
if axis != 0:
result = _nx.moveaxis(result, 0, axis)
diff --git a/numpy/core/tests/test_function_base.py b/numpy/core/tests/test_function_base.py
index 2197ef0cd..62a9772c8 100644
--- a/numpy/core/tests/test_function_base.py
+++ b/numpy/core/tests/test_function_base.py
@@ -1,6 +1,6 @@
from numpy import (
logspace, linspace, geomspace, dtype, array, sctypes, arange, isnan,
- ndarray, sqrt, nextafter, stack
+ ndarray, sqrt, nextafter, stack, errstate
)
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_array_equal, assert_allclose,
@@ -113,6 +113,40 @@ class TestGeomspace:
assert_array_equal(y, [-100, -10, -1])
assert_array_equal(y.imag, 0)
+ def test_boundaries_match_start_and_stop_exactly(self):
+ # make sure that the boundaries of the returned array exactly
+ # equal 'start' and 'stop' - this isn't obvious because
+ # np.exp(np.log(x)) isn't necessarily exactly equal to x
+ start = 0.3
+ stop = 20.3
+
+ y = geomspace(start, stop, num=1)
+ assert_equal(y[0], start)
+
+ y = geomspace(start, stop, num=1, endpoint=False)
+ assert_equal(y[0], start)
+
+ y = geomspace(start, stop, num=3)
+ assert_equal(y[0], start)
+ assert_equal(y[-1], stop)
+
+ y = geomspace(start, stop, num=3, endpoint=False)
+ assert_equal(y[0], start)
+
+ def test_nan_interior(self):
+ with errstate(invalid='ignore'):
+ y = geomspace(-3, 3, num=4)
+
+ assert_equal(y[0], -3.0)
+ assert_(isnan(y[1:-1]).all())
+ assert_equal(y[3], 3.0)
+
+ with errstate(invalid='ignore'):
+ y = geomspace(-3, 3, num=4, endpoint=False)
+
+ assert_equal(y[0], -3.0)
+ assert_(isnan(y[1:]).all())
+
def test_complex(self):
# Purely imaginary
y = geomspace(1j, 16j, num=5)