Skip to content

Commit db5592e

Browse files
Copilotoyamad
andauthored
Deprecate util.array.searchsorted in favor of np.searchsorted (#816)
* Initial plan * Replace searchsorted with np.searchsorted and add deprecation warning Co-authored-by: oyamad <7353083+oyamad@users.noreply.github.com> * Incorporate changes from deprecate_searchsorted branch and fix indentation - Reverted array.py and test_array.py to use the implementation from commit ab0fa74 - This version keeps the JIT-compiled searchsorted but emits deprecation warning - Fixed indentation in markov/core.py line 666 as suggested in code review - Removed unused numpy import from array.py Co-authored-by: oyamad <7353083+oyamad@users.noreply.github.com> * Add a test case with jitted function --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: oyamad <7353083+oyamad@users.noreply.github.com> Co-authored-by: Daisuke Oyama <oyama@e.u-tokyo.ac.jp>
1 parent 83d3c6c commit db5592e

File tree

4 files changed

+41
-10
lines changed

4 files changed

+41
-10
lines changed

quantecon/markov/core.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787

8888
from .gth_solve import gth_solve
8989
from .._graph_tools import DiGraph
90-
from ..util import searchsorted, check_random_state, rng_integers
90+
from ..util import check_random_state, rng_integers
9191

9292

9393
class MarkovChain:
@@ -618,7 +618,7 @@ def _generate_sample_paths(P_cdfs, init_states, random_values, out):
618618
for i in range(num_reps):
619619
out[i, 0] = init_states[i]
620620
for t in range(ts_length-1):
621-
out[i, t+1] = searchsorted(P_cdfs[out[i, t]], random_values[i, t])
621+
out[i, t+1] = np.searchsorted(P_cdfs[out[i, t]], random_values[i, t], side='right')
622622

623623

624624
@jit(nopython=True)
@@ -662,8 +662,8 @@ def _generate_sample_paths_sparse(P_cdfs1d, indices, indptr, init_states,
662662
for i in range(num_reps):
663663
out[i, 0] = init_states[i]
664664
for t in range(ts_length-1):
665-
k = searchsorted(P_cdfs1d[indptr[out[i, t]]:indptr[out[i, t]+1]],
666-
random_values[i, t])
665+
k = np.searchsorted(P_cdfs1d[indptr[out[i, t]]:indptr[out[i, t]+1]],
666+
random_values[i, t], side='right')
667667
out[i, t+1] = indices[indptr[out[i, t]]+k]
668668

669669

@@ -719,7 +719,7 @@ def mc_sample_path(P, init=0, sample_size=1000, random_state=None):
719719
else:
720720
cdf0 = np.cumsum(init)
721721
u_0 = random_state.random()
722-
X_0 = searchsorted(cdf0, u_0)
722+
X_0 = np.searchsorted(cdf0, u_0, side='right')
723723

724724
mc = MarkovChain(P)
725725
return mc.simulate(ts_length=sample_size, init=X_0,

quantecon/random/utilities.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import numpy as np
77
from numba import guvectorize, types
88
from numba.extending import overload
9-
from ..util import check_random_state, searchsorted
9+
from ..util import check_random_state
1010

1111

1212
# Generating Arrays and Vectors #
@@ -204,7 +204,7 @@ def draw(cdf, size=None):
204204
return out
205205
else:
206206
r = np.random.random()
207-
return searchsorted(cdf, r)
207+
return np.searchsorted(cdf, r, side='right')
208208

209209

210210
# Overload for the `draw` function
@@ -215,10 +215,10 @@ def draw_impl(cdf, size=None):
215215
rs = np.random.random(size)
216216
out = np.empty(size, dtype=np.int_)
217217
for i in range(size):
218-
out[i] = searchsorted(cdf, rs[i])
218+
out[i] = np.searchsorted(cdf, rs[i], side='right')
219219
return out
220220
else:
221221
def draw_impl(cdf, size=None):
222222
r = np.random.random()
223-
return searchsorted(cdf, r)
223+
return np.searchsorted(cdf, r, side='right')
224224
return draw_impl

quantecon/util/array.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
99
"""
1010

11-
from numba import jit
11+
import warnings
12+
from numba import jit, objmode
1213

1314
# ----------------- #
1415
# -ARRAY UTILITIES- #
@@ -21,6 +22,10 @@ def searchsorted(a, v):
2122
that `a[i-1] <= v < a[i]` (for `i = 0`, `v < a[0]`); if `v[n-1] <=
2223
v`, return `n`, where `n = len(a)`.
2324
25+
.. deprecated::
26+
27+
Deprecated, use `np.searchsorted(a, v, side='right')` instead.
28+
2429
Parameters
2530
----------
2631
a : ndarray(float, ndim=1)
@@ -51,6 +56,14 @@ def searchsorted(a, v):
5156
3
5257
5358
"""
59+
with objmode():
60+
warnings.warn(
61+
"`searchsorted(a, v)` is deprecated. "
62+
"Use `np.searchsorted(a, v, side='right')` instead.",
63+
DeprecationWarning,
64+
stacklevel=2,
65+
)
66+
5467
lo = -1
5568
hi = len(a)
5669
while(lo < hi-1):

quantecon/util/tests/test_array.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
"""
99
import numpy as np
1010
from numpy.testing import assert_
11+
from numba import njit
12+
import pytest
1113
from quantecon.util import searchsorted
1214

1315

16+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
1417
def test_searchsorted():
1518
a = np.array([0.2, 0.4, 1.0])
1619
assert_(searchsorted(a, 0.1) == 0)
@@ -28,3 +31,18 @@ def test_searchsorted():
2831
a = np.ones(2)
2932
for (v, i) in zip([0, 1, 2], [0, 2, 2]):
3033
assert_(searchsorted(a, v) == i)
34+
35+
36+
@njit
37+
def _jitted_function():
38+
a = np.array([0.2, 0.4, 1.0])
39+
return searchsorted(a, 0.5)
40+
41+
42+
def test_warns():
43+
a = np.array([0.2, 0.4, 1.0])
44+
with pytest.warns(DeprecationWarning):
45+
searchsorted(a, 0.5)
46+
47+
with pytest.warns(DeprecationWarning):
48+
_jitted_function()

0 commit comments

Comments
 (0)