forked from lenskit/lkpy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_argtopn.py
More file actions
72 lines (57 loc) · 2.04 KB
/
Copy pathtest_argtopn.py
File metadata and controls
72 lines (57 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# This file is part of LensKit.
# Copyright (C) 2018-2023 Boise State University.
# Copyright (C) 2023-2025 Drexel University.
# Licensed under the MIT license, see LICENSE.md for details.
# SPDX-License-Identifier: MIT
import numpy as np
import hypothesis.extra.numpy as nph
import hypothesis.strategies as st
from hypothesis import given, settings
from lenskit.data.types import argtopn
def test_simple_topn():
positions = argtopn([1.0, 0.0], 1)
assert len(positions) == 1
assert positions[0] == 0
def test_simple_topn_rev():
positions = argtopn([0.0, 1.0], 1)
assert len(positions) == 1
assert positions[0] == 1
@given(
nph.arrays(nph.floating_dtypes(endianness="="), st.integers(0, 5000)), st.integers(min_value=-1)
)
def test_arg_topn(xs, k):
positions = argtopn(xs, k)
if k >= 0:
assert len(positions) <= k
assert positions.dtype == np.int64
if k == 0 or np.all(np.isnan(xs)):
assert len(positions) == 0
return
top_xs = xs[positions]
sort_xs = np.sort(-xs[~np.isnan(xs)])
# we have the correct number of positions
if k >= 0:
assert len(positions) == min(k, np.sum(~np.isnan(xs)))
else:
assert len(positions) == np.sum(~np.isnan(xs))
# all rank positions are valid
assert np.all(positions >= 0)
assert np.all(positions < len(xs))
# all rank positions are unique
assert len(np.unique(positions)) == len(positions)
# all ranked items are numbers
assert not np.any(np.isnan(top_xs))
# we have the largest values
if len(positions) < k:
omitted = np.ones(len(xs), dtype="bool")
omitted[positions] = False
if not np.all(np.isnan(xs[omitted])):
assert np.all(top_xs >= np.nanmax(xs[omitted]))
# the values are sorted
if len(top_xs) > 1:
assert np.all(top_xs[:-1] >= top_xs[1:])
# the min matches the underlying sort
if k >= 1:
assert top_xs[-1] == -sort_xs[min(k - 1, len(sort_xs) - 1)]
elif np.all(np.isfinite(sort_xs)):
assert np.all(top_xs == -sort_xs)