math.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. #ifndef __PJ_MATH_H__
  20. #define __PJ_MATH_H__
  21. /**
  22. * @file math.h
  23. * @brief Mathematics and Statistics.
  24. */
  25. #include <pj/string.h>
  26. #include <pj/compat/high_precision.h>
  27. PJ_BEGIN_DECL
  28. /**
  29. * @defgroup pj_math Mathematics and Statistics
  30. * @ingroup PJ_MISC
  31. * @{
  32. *
  33. * Provides common mathematics constants and operations, and also standard
  34. * statistics calculation (min, max, mean, standard deviation). Statistics
  35. * calculation is done in realtime (statistics state is updated on time each
  36. * new sample comes).
  37. */
  38. /**
  39. * Mathematical constants
  40. */
  41. /** pi */
  42. #define PJ_PI 3.14159265358979323846 /* pi */
  43. /** 1/pi */
  44. #define PJ_1_PI 0.318309886183790671538 /* 1/pi */
  45. /**
  46. * Mathematical macros
  47. */
  48. /** Get the absolute value */
  49. #define PJ_ABS(x) ((x) > 0 ? (x) : -(x))
  50. /** Get the maximum of two values */
  51. #define PJ_MAX(x, y) ((x) > (y)? (x) : (y))
  52. /** Get the minimum of two values */
  53. #define PJ_MIN(x, y) ((x) < (y)? (x) : (y))
  54. /**
  55. * This structure describes statistics state.
  56. */
  57. typedef struct pj_math_stat
  58. {
  59. int n; /**< number of samples */
  60. int max; /**< maximum value */
  61. int min; /**< minimum value */
  62. int last; /**< last value */
  63. int mean; /**< mean */
  64. /* Private members */
  65. #if PJ_HAS_FLOATING_POINT
  66. float fmean_; /**< mean(floating point) */
  67. #else
  68. int mean_res_; /**< mean residue */
  69. #endif
  70. pj_highprec_t m2_; /**< variance * n */
  71. } pj_math_stat;
  72. /**
  73. * Calculate integer square root of an integer.
  74. *
  75. * @param i Integer to be calculated.
  76. *
  77. * @return Square root result.
  78. */
  79. PJ_INLINE(unsigned) pj_isqrt(unsigned i)
  80. {
  81. unsigned res = 1, prev;
  82. /* Rough guess, calculate half bit of input */
  83. prev = i >> 2;
  84. while (prev) {
  85. prev >>= 2;
  86. res <<= 1;
  87. }
  88. /* Babilonian method */
  89. do {
  90. prev = res;
  91. res = (prev + i/prev) >> 1;
  92. } while ((prev+res)>>1 != res);
  93. return res;
  94. }
  95. /**
  96. * Initialize statistics state.
  97. *
  98. * @param stat Statistic state.
  99. */
  100. PJ_INLINE(void) pj_math_stat_init(pj_math_stat *stat)
  101. {
  102. pj_bzero(stat, sizeof(pj_math_stat));
  103. }
  104. /**
  105. * Update statistics state as a new sample comes.
  106. *
  107. * @param stat Statistic state.
  108. * @param val The new sample data.
  109. */
  110. PJ_INLINE(void) pj_math_stat_update(pj_math_stat *stat, int val)
  111. {
  112. #if PJ_HAS_FLOATING_POINT
  113. float delta;
  114. #else
  115. int delta;
  116. #endif
  117. stat->last = val;
  118. if (stat->n++) {
  119. if (stat->min > val)
  120. stat->min = val;
  121. if (stat->max < val)
  122. stat->max = val;
  123. } else {
  124. stat->min = stat->max = val;
  125. }
  126. #if PJ_HAS_FLOATING_POINT
  127. delta = val - stat->fmean_;
  128. stat->fmean_ += delta/stat->n;
  129. /* Return mean value with 'rounding' */
  130. stat->mean = (int) (stat->fmean_ + 0.5);
  131. stat->m2_ += (int)(delta * (val-stat->fmean_));
  132. #else
  133. delta = val - stat->mean;
  134. stat->mean += delta/stat->n;
  135. stat->mean_res_ += delta % stat->n;
  136. if (stat->mean_res_ >= stat->n) {
  137. ++stat->mean;
  138. stat->mean_res_ -= stat->n;
  139. } else if (stat->mean_res_ <= -stat->n) {
  140. --stat->mean;
  141. stat->mean_res_ += stat->n;
  142. }
  143. stat->m2_ += delta * (val-stat->mean);
  144. #endif
  145. }
  146. /**
  147. * Get the standard deviation of specified statistics state.
  148. *
  149. * @param stat Statistic state.
  150. *
  151. * @return The standard deviation.
  152. */
  153. PJ_INLINE(unsigned) pj_math_stat_get_stddev(const pj_math_stat *stat)
  154. {
  155. if (stat->n == 0) return 0;
  156. return (pj_isqrt((unsigned)(stat->m2_/stat->n)));
  157. }
  158. /**
  159. * Set the standard deviation of statistics state. This is useful when
  160. * the statistic state is operated in 'read-only' mode as a storage of
  161. * statistical data.
  162. *
  163. * @param stat Statistic state.
  164. *
  165. * @param dev The standard deviation.
  166. */
  167. PJ_INLINE(void) pj_math_stat_set_stddev(pj_math_stat *stat, unsigned dev)
  168. {
  169. if (stat->n == 0)
  170. stat->n = 1;
  171. stat->m2_ = dev*dev*stat->n;
  172. }
  173. /** @} */
  174. PJ_END_DECL
  175. #endif /* __PJ_MATH_H__ */