/src/pjsip/pjlib/include/pj/math.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
3 | | * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
4 | | * |
5 | | * This program is free software; you can redistribute it and/or modify |
6 | | * it under the terms of the GNU General Public License as published by |
7 | | * the Free Software Foundation; either version 2 of the License, or |
8 | | * (at your option) any later version. |
9 | | * |
10 | | * This program is distributed in the hope that it will be useful, |
11 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | * GNU General Public License for more details. |
14 | | * |
15 | | * You should have received a copy of the GNU General Public License |
16 | | * along with this program; if not, write to the Free Software |
17 | | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | | */ |
19 | | |
20 | | #ifndef __PJ_MATH_H__ |
21 | | #define __PJ_MATH_H__ |
22 | | |
23 | | /** |
24 | | * @file math.h |
25 | | * @brief Mathematics and Statistics. |
26 | | */ |
27 | | |
28 | | #include <pj/string.h> |
29 | | #include <pj/compat/high_precision.h> |
30 | | |
31 | | PJ_BEGIN_DECL |
32 | | |
33 | | /** |
34 | | * @defgroup pj_math Mathematics and Statistics |
35 | | * @ingroup PJ_MISC |
36 | | * @{ |
37 | | * |
38 | | * Provides common mathematics constants and operations, and also standard |
39 | | * statistics calculation (min, max, mean, standard deviation). Statistics |
40 | | * calculation is done in realtime (statistics state is updated on time each |
41 | | * new sample comes). |
42 | | */ |
43 | | |
44 | | /** |
45 | | * Mathematical constants |
46 | | */ |
47 | | /** pi */ |
48 | | #define PJ_PI 3.14159265358979323846 /* pi */ |
49 | | /** 1/pi */ |
50 | | #define PJ_1_PI 0.318309886183790671538 /* 1/pi */ |
51 | | |
52 | | /** |
53 | | * Mathematical macros |
54 | | */ |
55 | | /** Get the absolute value */ |
56 | | #define PJ_ABS(x) ((x) > 0 ? (x) : -(x)) |
57 | | |
58 | | /** Get the maximum of two values */ |
59 | | #define PJ_MAX(x, y) ((x) > (y)? (x) : (y)) |
60 | | |
61 | | /** Get the minimum of two values */ |
62 | 3.61k | #define PJ_MIN(x, y) ((x) < (y)? (x) : (y)) |
63 | | |
64 | | /** |
65 | | * This structure describes statistics state. |
66 | | */ |
67 | | typedef struct pj_math_stat |
68 | | { |
69 | | int n; /**< number of samples */ |
70 | | int max; /**< maximum value */ |
71 | | int min; /**< minimum value */ |
72 | | int last; /**< last value */ |
73 | | int mean; /**< mean */ |
74 | | |
75 | | /* Private members */ |
76 | | #if PJ_HAS_FLOATING_POINT |
77 | | float fmean_; /**< mean(floating point) */ |
78 | | #else |
79 | | int mean_res_; /**< mean residue */ |
80 | | #endif |
81 | | pj_highprec_t m2_; /**< variance * n */ |
82 | | } pj_math_stat; |
83 | | |
84 | | /** |
85 | | * Calculate integer square root of an integer. |
86 | | * |
87 | | * @param i Integer to be calculated. |
88 | | * |
89 | | * @return Square root result. |
90 | | */ |
91 | | PJ_INLINE(unsigned) pj_isqrt(unsigned i) |
92 | 0 | { |
93 | 0 | unsigned res = 1, prev; |
94 | 0 | |
95 | 0 | /* Rough guess, calculate half bit of input */ |
96 | 0 | prev = i >> 2; |
97 | 0 | while (prev) { |
98 | 0 | prev >>= 2; |
99 | 0 | res <<= 1; |
100 | 0 | } |
101 | 0 |
|
102 | 0 | /* Babilonian method */ |
103 | 0 | do { |
104 | 0 | prev = res; |
105 | 0 | res = (prev + i/prev) >> 1; |
106 | 0 | } while ((prev+res)>>1 != res); |
107 | 0 |
|
108 | 0 | return res; |
109 | 0 | } Unexecuted instantiation: fuzz-rtcp.c:pj_isqrt Unexecuted instantiation: event.c:pj_isqrt Unexecuted instantiation: rtcp.c:pj_isqrt Unexecuted instantiation: rtcp_fb.c:pj_isqrt Unexecuted instantiation: vid_codec.c:pj_isqrt Unexecuted instantiation: codec.c:pj_isqrt Unexecuted instantiation: endpoint.c:pj_isqrt |
110 | | |
111 | | /** |
112 | | * Initialize statistics state. |
113 | | * |
114 | | * @param stat Statistic state. |
115 | | */ |
116 | | PJ_INLINE(void) pj_math_stat_init(pj_math_stat *stat) |
117 | 3.39k | { |
118 | 3.39k | pj_bzero(stat, sizeof(pj_math_stat)); |
119 | 3.39k | } Unexecuted instantiation: fuzz-rtcp.c:pj_math_stat_init Unexecuted instantiation: event.c:pj_math_stat_init Line | Count | Source | 117 | 3.39k | { | 118 | 3.39k | pj_bzero(stat, sizeof(pj_math_stat)); | 119 | 3.39k | } |
Unexecuted instantiation: rtcp_fb.c:pj_math_stat_init Unexecuted instantiation: vid_codec.c:pj_math_stat_init Unexecuted instantiation: codec.c:pj_math_stat_init Unexecuted instantiation: endpoint.c:pj_math_stat_init |
120 | | |
121 | | /** |
122 | | * Update statistics state as a new sample comes. |
123 | | * |
124 | | * @param stat Statistic state. |
125 | | * @param val The new sample data. |
126 | | */ |
127 | | PJ_INLINE(void) pj_math_stat_update(pj_math_stat *stat, int val) |
128 | 4.95k | { |
129 | 4.95k | #if PJ_HAS_FLOATING_POINT |
130 | 4.95k | float delta; |
131 | | #else |
132 | | int delta; |
133 | | #endif |
134 | | |
135 | 4.95k | stat->last = val; |
136 | | |
137 | 4.95k | if (stat->n++) { |
138 | 4.38k | if (stat->min > val) |
139 | 292 | stat->min = val; |
140 | 4.38k | if (stat->max < val) |
141 | 327 | stat->max = val; |
142 | 4.38k | } else { |
143 | 571 | stat->min = stat->max = val; |
144 | 571 | } |
145 | | |
146 | 4.95k | #if PJ_HAS_FLOATING_POINT |
147 | 4.95k | delta = val - stat->fmean_; |
148 | 4.95k | stat->fmean_ += delta/stat->n; |
149 | | |
150 | | /* Return mean value with 'rounding' */ |
151 | 4.95k | stat->mean = (int) (stat->fmean_ + 0.5); |
152 | | |
153 | 4.95k | stat->m2_ += (int)(delta * (val-stat->fmean_)); |
154 | | #else |
155 | | delta = val - stat->mean; |
156 | | stat->mean += delta/stat->n; |
157 | | stat->mean_res_ += delta % stat->n; |
158 | | if (stat->mean_res_ >= stat->n) { |
159 | | ++stat->mean; |
160 | | stat->mean_res_ -= stat->n; |
161 | | } else if (stat->mean_res_ <= -stat->n) { |
162 | | --stat->mean; |
163 | | stat->mean_res_ += stat->n; |
164 | | } |
165 | | |
166 | | stat->m2_ += delta * (val-stat->mean); |
167 | | #endif |
168 | 4.95k | } Unexecuted instantiation: fuzz-rtcp.c:pj_math_stat_update Unexecuted instantiation: event.c:pj_math_stat_update rtcp.c:pj_math_stat_update Line | Count | Source | 128 | 4.95k | { | 129 | 4.95k | #if PJ_HAS_FLOATING_POINT | 130 | 4.95k | float delta; | 131 | | #else | 132 | | int delta; | 133 | | #endif | 134 | | | 135 | 4.95k | stat->last = val; | 136 | | | 137 | 4.95k | if (stat->n++) { | 138 | 4.38k | if (stat->min > val) | 139 | 292 | stat->min = val; | 140 | 4.38k | if (stat->max < val) | 141 | 327 | stat->max = val; | 142 | 4.38k | } else { | 143 | 571 | stat->min = stat->max = val; | 144 | 571 | } | 145 | | | 146 | 4.95k | #if PJ_HAS_FLOATING_POINT | 147 | 4.95k | delta = val - stat->fmean_; | 148 | 4.95k | stat->fmean_ += delta/stat->n; | 149 | | | 150 | | /* Return mean value with 'rounding' */ | 151 | 4.95k | stat->mean = (int) (stat->fmean_ + 0.5); | 152 | | | 153 | 4.95k | stat->m2_ += (int)(delta * (val-stat->fmean_)); | 154 | | #else | 155 | | delta = val - stat->mean; | 156 | | stat->mean += delta/stat->n; | 157 | | stat->mean_res_ += delta % stat->n; | 158 | | if (stat->mean_res_ >= stat->n) { | 159 | | ++stat->mean; | 160 | | stat->mean_res_ -= stat->n; | 161 | | } else if (stat->mean_res_ <= -stat->n) { | 162 | | --stat->mean; | 163 | | stat->mean_res_ += stat->n; | 164 | | } | 165 | | | 166 | | stat->m2_ += delta * (val-stat->mean); | 167 | | #endif | 168 | 4.95k | } |
Unexecuted instantiation: rtcp_fb.c:pj_math_stat_update Unexecuted instantiation: vid_codec.c:pj_math_stat_update Unexecuted instantiation: codec.c:pj_math_stat_update Unexecuted instantiation: endpoint.c:pj_math_stat_update |
169 | | |
170 | | /** |
171 | | * Get the standard deviation of specified statistics state. |
172 | | * |
173 | | * @param stat Statistic state. |
174 | | * |
175 | | * @return The standard deviation. |
176 | | */ |
177 | | PJ_INLINE(unsigned) pj_math_stat_get_stddev(const pj_math_stat *stat) |
178 | 0 | { |
179 | 0 | if (stat->n == 0) return 0; |
180 | 0 | return (pj_isqrt((unsigned)(stat->m2_/stat->n))); |
181 | 0 | } Unexecuted instantiation: fuzz-rtcp.c:pj_math_stat_get_stddev Unexecuted instantiation: event.c:pj_math_stat_get_stddev Unexecuted instantiation: rtcp.c:pj_math_stat_get_stddev Unexecuted instantiation: rtcp_fb.c:pj_math_stat_get_stddev Unexecuted instantiation: vid_codec.c:pj_math_stat_get_stddev Unexecuted instantiation: codec.c:pj_math_stat_get_stddev Unexecuted instantiation: endpoint.c:pj_math_stat_get_stddev |
182 | | |
183 | | /** |
184 | | * Set the standard deviation of statistics state. This is useful when |
185 | | * the statistic state is operated in 'read-only' mode as a storage of |
186 | | * statistical data. |
187 | | * |
188 | | * @param stat Statistic state. |
189 | | * |
190 | | * @param dev The standard deviation. |
191 | | */ |
192 | | PJ_INLINE(void) pj_math_stat_set_stddev(pj_math_stat *stat, unsigned dev) |
193 | 0 | { |
194 | 0 | if (stat->n == 0) |
195 | 0 | stat->n = 1; |
196 | 0 | stat->m2_ = dev*dev*stat->n; |
197 | 0 | } Unexecuted instantiation: fuzz-rtcp.c:pj_math_stat_set_stddev Unexecuted instantiation: event.c:pj_math_stat_set_stddev Unexecuted instantiation: rtcp.c:pj_math_stat_set_stddev Unexecuted instantiation: rtcp_fb.c:pj_math_stat_set_stddev Unexecuted instantiation: vid_codec.c:pj_math_stat_set_stddev Unexecuted instantiation: codec.c:pj_math_stat_set_stddev Unexecuted instantiation: endpoint.c:pj_math_stat_set_stddev |
198 | | |
199 | | /** @} */ |
200 | | |
201 | | PJ_END_DECL |
202 | | |
203 | | #endif /* __PJ_MATH_H__ */ |