Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -*- coding: utf-8 -*- 

2# This file is part of Xpra. 

3# Copyright (C) 2012-2019 Antoine Martin <antoine@xpra.org> 

4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any 

5# later version. See the file COPYING for details. 

6 

7# Simple statistical functions 

8 

9import math 

10 

11def to_std_unit(v, unit=1000): 

12 if v>=unit**3: 

13 return "G", v//(unit**3) 

14 if v>=unit**2: 

15 return "M", v//(unit**2) 

16 if v>=unit: 

17 return "K", v//unit 

18 return "", v 

19 

20def std_unit(v, unit=1000) -> str: 

21 unit, value = to_std_unit(v, unit) 

22 return "%s%s" % (int(value), unit) 

23 

24def std_unit_dec(v): 

25 unit, value = to_std_unit(v*10.0) 

26 if value>=100: 

27 return "%s%s" % (int(value//10), unit) 

28 if int(value)%10==0: 

29 return "%s%s" % (int(value/10), unit) 

30 return "%s%s" % (int(value)/10.0, unit) 

31 

32 

33def absolute_to_diff_values(in_data): 

34 """ Given a list of values, return a new list 

35 containing the incremental diff between each value 

36 ie: [0,2,2,10] -> [2,0,8] 

37 """ 

38 last_value = None 

39 data = [] 

40 for x in in_data: 

41 if last_value is not None: 

42 data.append(x-last_value) 

43 last_value = x 

44 return data 

45 

46def values_to_scaled_values(data, scale_unit=10, min_scaled_value=10, num_values=20): 

47 #print("values_to_scaled_values(%s, %s, %s)" % (data, scale_unit, num_values)) 

48 if not data: 

49 return 0, data 

50 max_v = max(data) 

51 #pad with None values so we have at least num_values: 

52 if len(data)<num_values: 

53 if isinstance(data, tuple): 

54 data = list(data) 

55 for _ in range(num_values-len(data)): 

56 data.insert(0, None) 

57 scale = 1 

58 assert scale_unit>1 

59 while scale*scale_unit*min_scaled_value<=max_v: 

60 scale *= scale_unit 

61 if scale==1: 

62 return scale, data 

63 sdata = [] 

64 for x in data: 

65 if x is None: 

66 sdata.append(None) 

67 else: 

68 sdata.append(x/scale) 

69 return scale, sdata 

70 

71def values_to_diff_scaled_values(data, scale_unit=10, min_scaled_value=10, num_values=20): 

72 return values_to_scaled_values(absolute_to_diff_values(data), scale_unit=scale_unit, min_scaled_value=min_scaled_value, num_values=num_values) 

73 

74def get_weighted_list_stats(weighted_values, show_percentile=False): 

75 values = tuple(x[0] for x in weighted_values) 

76 if not values: 

77 return {} 

78 #weighted mean: 

79 tw = 0 

80 tv = 0 

81 for v, w in weighted_values: 

82 tw += w 

83 tv += v * w 

84 avg = tv/tw 

85 stats = { 

86 "min" : int(min(values)), 

87 "max" : int(max(values)), 

88 "avg" : int(avg), 

89 } 

90 if show_percentile: 

91 #percentile 

92 svalues = sorted(values) 

93 for i in range(1,10): 

94 pct = i*10 

95 index = len(values)*i//10 

96 stats["%ip" % pct] = int(svalues[index]) 

97 return stats 

98 

99 

100def find_invpow(x, n): 

101 """Finds the integer component of the n'th root of x, 

102 an integer such that y ** n <= x < (y + 1) ** n. 

103 """ 

104 high = 1 

105 while high ** n < x: 

106 high *= 2 

107 low = high/2 

108 while low < high: 

109 mid = (low + high) // 2 

110 if low < mid and mid**n < x: 

111 low = mid 

112 elif high > mid and mid**n > x: 

113 high = mid 

114 else: 

115 return mid 

116 return mid + 1 

117 

118def get_list_stats(in_values, show_percentile=(5, 8, 9), show_dev=False): 

119 #this may be backed by a deque/list whichi is used by other threads 

120 #so make a copy before use: 

121 values = tuple(in_values) 

122 if not values: 

123 return {} 

124 #arithmetic mean 

125 avg = sum(values)/len(values) 

126 lstats = { 

127 "cur" : int(values[-1]), 

128 "min" : int(min(values)), 

129 "max" : int(max(values)), 

130 "avg" : int(avg), 

131 } 

132 if show_dev: 

133 p = 1 #geometric mean 

134 h = 0 #harmonic mean 

135 var = 0 #variance 

136 counter = 0 

137 for x in values: 

138 if x!=0: 

139 p *= x 

140 h += 1.0/x 

141 counter += 1 

142 var += (x-avg)**2 

143 #standard deviation: 

144 std = math.sqrt(var/len(values)) 

145 lstats["std"] = int(std) 

146 if avg!=0: 

147 #coefficient of variation 

148 lstats["cv_pct"] = int(100.0*std/avg) 

149 if counter>0 and p<float('inf'): 

150 #geometric mean 

151 try: 

152 v = int(math.pow(p, 1.0/counter)) 

153 except OverflowError: 

154 v = find_invpow(p, counter) 

155 lstats["gm"] = v 

156 if h!=0: 

157 #harmonic mean 

158 lstats["h"] = int(counter/h) 

159 if show_percentile: 

160 #percentile 

161 svalues = sorted(values) 

162 for i in show_percentile: 

163 pct = i*10 

164 index = len(values)*i//10 

165 lstats["%ip" % pct] = int(svalues[index]) 

166 return lstats