1 from __future__ import annotations

2

3 import numpy as np

4

5 from muutils.statcounter import StatCounter

6

7

8 def _compute_err(a: float, b: float, /) -> dict[str, float]:

9 return dict(

10 num_a=float(a),

11 num_b=float(b),

12 diff=float(b - a),

13 # frac_err=float((b - a) / a), # this causes division by zero, whatever

14 )

15

16

17 def _compare_np_custom(arr: np.ndarray) -> dict[str, dict]:

18 counter: StatCounter = StatCounter(arr)

19 return dict(

20 mean=_compute_err(counter.mean(), np.mean(arr)),

21 std=_compute_err(counter.std(), np.std(arr)),

22 min=_compute_err(counter.min(), np.min(arr)),

23 q1=_compute_err(counter.percentile(0.25), np.percentile(arr, 25)),

24 median=_compute_err(counter.median(), np.median(arr)),

25 q3=_compute_err(counter.percentile(0.75), np.percentile(arr, 75)),

26 max=_compute_err(counter.max(), np.max(arr)),

27 )

28

29

30 EPSILON: float = 1e-8

31

32

33 def test_statcounter() -> None:

34 arrs: list[np.ndarray] = [

35 np.array([0, 1]),

36 np.array([1, 2]),

37 np.random.randint(0, 10, size=10),

38 np.random.randint(-5, 15, size=10),

39 np.array([-5, -4, -1, 1, 1, 3, 3, 5, 11, 12]),

40 np.random.randint(-5, 15, size=100),

41 np.random.randint(0, 100, size=100),

42 np.random.randint(0, 1000, size=100),

43 ]

44

45 # for i, j in np.random.randint(1, 100, size=(50, 2)):

46 # if i > j:

47 # i, j = j, i

48

49 # arrs.append(np.random.randint(i, j, size=1000))

50

51 for a in arrs:

52 r = _compare_np_custom(a)

53

54 assert all(

55 [x["diff"] < EPSILON for x in r.values()]

56 ), f"errs for rantint array: {a.shape = } {np.min(a) = } {np.max(a) = } data = {r}"

57 # s = StatCounter(a)

58 # print(s.total(), s)

59 # print(sorted(list(s.elements())))