From a33c7aeaee65347f44c7da1612c904b7becb324f Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Sat, 17 May 2008 14:43:46 +0000 Subject: Ticket #535: added initial source of math.h git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1960 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/math.h | 193 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 pjlib/include/pj/math.h (limited to 'pjlib/include') diff --git a/pjlib/include/pj/math.h b/pjlib/include/pj/math.h new file mode 100644 index 00000000..c8f7ce48 --- /dev/null +++ b/pjlib/include/pj/math.h @@ -0,0 +1,193 @@ +/* $Id$ */ +/* + * Copyright (C) 2003-2008 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PJ_MATH_H__ +#define __PJ_MATH_H__ + +/** + * @file math.h + * @brief Mathematics and Statistics. + */ + +#include +#include + +PJ_BEGIN_DECL + +/** + * @defgroup pj_math Mathematics and Statistics + * @ingroup PJ_MISC + * @{ + * + * Provides common mathematics constants and operations, and also standard + * statistics calculation (min, max, mean, standard deviation). Statistics + * calculation is done in realtime (statistics state is updated on time each + * new sample comes). + */ + +/** + * Mathematical constants + */ +#define PJ_PI 3.14159265358979323846 /* pi */ +#define PJ_1_PI 0.318309886183790671538 /* 1/pi */ + +/** + * Mathematical macro + */ +#define PJ_ABS(x) ((x) > 0 ? (x) : -(x)) +#define PJ_MAX(x, y) ((x) > (y)? (x) : (y)) +#define PJ_MIN(x, y) ((x) < (y)? (x) : (y)) + +/** + * This structure describes statistics state. + */ +typedef struct pj_math_stat +{ + int n; /* number of samples */ + int max; /* maximum value */ + int min; /* minimum value */ + int last; /* last value */ + int mean; /* mean */ + + /* Private members */ +#if PJ_HAS_FLOATING_POINT + float fmean_; /* mean(floating point) */ +#else + int mean_res_; /* mean residu */ +#endif + pj_highprec_t m2_; /* variance * n */ +} pj_math_stat; + +/** + * Calculate integer square root of an integer. + * + * @param i Integer to be calculated. + * + * @return Square root result. + */ +PJ_INLINE(unsigned) pj_isqrt(unsigned i) +{ + unsigned res = 1, prev; + + /* Rough guess, calculate half bit of input */ + prev = i >> 2; + while (prev) { + prev >>= 2; + res <<= 1; + } + + /* Babilonian method */ + do { + prev = res; + res = (prev + i/prev) >> 1; + } while ((prev+res)>>1 != res); + + return res; +} + +/** + * Initialize statistics state. + * + * @param stat Statistic state. + */ +PJ_INLINE(void) pj_math_stat_init(pj_math_stat *stat) +{ + pj_bzero(stat, sizeof(pj_math_stat)); +} + +/** + * Update statistics state as a new sample comes. + * + * @param stat Statistic state. + * @param val The new sample data. + */ +PJ_INLINE(void) pj_math_stat_update(pj_math_stat *stat, int val) +{ +#if PJ_HAS_FLOATING_POINT + float delta; +#else + int delta; +#endif + + stat->last = val; + + if (stat->n++) { + if (stat->min > val) + stat->min = val; + if (stat->max < val) + stat->max = val; + } else { + stat->min = stat->max = val; + } + +#if PJ_HAS_FLOATING_POINT + delta = val - stat->fmean_; + stat->fmean_ += delta/stat->n; + stat->mean = (int) stat->fmean_; + + stat->m2_ += (int)(delta * (val-stat->fmean_)); +#else + delta = val - stat->mean; + stat->mean += delta/stat->n; + stat->mean_res_ += delta % stat->n; + if (stat->mean_res_ >= stat->n) { + ++stat->mean; + stat->mean_res_ -= stat->n; + } else if (stat->mean_res_ <= -stat->n) { + --stat->mean; + stat->mean_res_ += stat->n; + } + + stat->m2_ += delta * (val-stat->mean); +#endif +} + +/** + * Get the standard deviation of specified statistics state. + * + * @param stat Statistic state. + * + * @return The standard deviation. + */ +PJ_INLINE(unsigned) pj_math_stat_get_stddev(pj_math_stat *stat) +{ + return (pj_isqrt((unsigned)(stat->m2_/stat->n))); +} + +/** + * Set the standard deviation of statistics state. This is useful when + * the statistic state is operated in 'read-only' mode as a storage of + * statistical data. + * + * @param stat Statistic state. + * + * @param dev The standard deviation. + */ +PJ_INLINE(void) pj_math_stat_set_stddev(pj_math_stat *stat, unsigned dev) +{ + if (stat->n == 0) + stat->n = 1; + stat->m2_ = dev*dev*stat->n; +} + +/** @} */ + +PJ_END_DECL + +#endif /* __PJ_MATH_H__ */ -- cgit v1.2.3