File: depthstat.nim

package info (click to toggle)
mosdepth 0.3.11%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,960 kB
  • sloc: sh: 268; python: 132; makefile: 28
file content (79 lines) | stat: -rw-r--r-- 2,024 bytes parent folder | download
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
73
74
75
76
77
78
79

type
  depth_stat* = object
    cum_length*: int
    cum_depth*: uint64
    min_depth*: uint32
    max_depth*: uint32

type CountStat*[T:SomeOrdinal] = object
  counts: seq[T]
  n: int

proc initCountStat*[T](size:int=32768): CountStat[T] =
  return CountStat[T](counts: newSeq[T](size))

proc add*[T](c: var CountStat, value: T) {.inline.} =
  c.n.inc
  if value < 0:
    raise newException(IndexDefect, "error setting negative depth value:" & $value)
  else:
    c.counts[min(c.counts.high.T, value)].inc

proc median*[T](c: CountStat[T]): int {.inline.} =
  var stop_n = int(0.5 + c.n.float64 * 0.5)
  var cum = 0
  for i, cnt in c.counts:
    cum += cnt.int
    if cum >= stop_n:
      return i
  return -1

proc clear*[T](c: var CountStat[T]) {.inline.} =
  if c.n == 0: return
  c.n = 0
  zeroMem(c.counts[0].addr, sizeof(c.counts[0]) * c.counts.len)

template len*[T](c:CountStat[T]): int = c.counts.len

proc newDepthStat*[T: SomeNumber](d: seq[T]): depth_stat =
  result.cum_length = len(d)
  result.min_depth = uint32.high
  for dp in d:
    result.cum_depth += dp.uint64
    result.min_depth = min(result.min_depth, dp.uint32)
    result.max_depth = max(result.max_depth, dp.uint32)

proc clear*(ds: var depth_stat) =
    ds.cum_length = 0
    ds.cum_depth = 0
    ds.min_depth = uint32.high
    ds.max_depth = 0

proc `+`*(a, b: depth_stat): depth_stat {.inline.} =
  result = depth_stat(cum_length: a.cum_length + b.cum_length,
                      cum_depth: a.cum_depth + b.cum_depth,
                      min_depth: min(a.min_depth, b.min_depth),
                      max_depth: max(a.max_depth, b.max_depth))

when isMainModule:
  import unittest
  suite "count-stat":
    test "count-test":

      var c = initCountStat[uint32]()
      for i in 0..10:
        c.add(i.uint32)

      check c.median == 5
      check c.n == 11
      check c.len == 32768

      c.add(6)
      c.add(6)
      c.add(6)
      c.add(6)
      check c.median == 6
      c.clear()
      check c.median == 0
      check c.n == 0