Tools.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. namespace VisualMath.Accord.Math
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using AForge;
  6. /// <summary>
  7. /// Set of mathematical tools.
  8. /// </summary>
  9. public static class Tools
  10. {
  11. #region Framework-wide random number generator
  12. private static Random random = new Random();
  13. /// <summary>
  14. /// Gets a reference to the random number generator used
  15. /// internally by the Accord.NET classes and methods.
  16. /// </summary>
  17. public static Random Random { get { return random; } }
  18. /// <summary>
  19. /// Sets a random seed for the internal number generator.
  20. /// </summary>
  21. /// <remarks>
  22. /// This method is only available in the debug version
  23. /// of the framework.
  24. /// </remarks>
  25. [System.Diagnostics.Conditional("DEBUG")]
  26. public static void SetRandomSeed(int seed)
  27. {
  28. #if DEBUG
  29. random = new Random(seed);
  30. #endif
  31. }
  32. #endregion
  33. /// <summary>
  34. /// Returns the next power of 2 after the input value x.
  35. /// </summary>
  36. /// <param name="x">Input value x.</param>
  37. /// <returns>Returns the next power of 2 after the input value x.</returns>
  38. public static int NextPowerOf2(int x)
  39. {
  40. --x;
  41. x |= x >> 1;
  42. x |= x >> 2;
  43. x |= x >> 4;
  44. x |= x >> 8;
  45. x |= x >> 16;
  46. return ++x;
  47. }
  48. /// <summary>
  49. /// Returns the previous power of 2 after the input value x.
  50. /// </summary>
  51. /// <param name="x">Input value x.</param>
  52. /// <returns>Returns the previous power of 2 after the input value x.</returns>
  53. public static int PreviousPowerOf2(int x)
  54. {
  55. return NextPowerOf2(x + 1) / 2;
  56. }
  57. /// <summary>
  58. /// Hypotenuse calculus without overflow/underflow
  59. /// </summary>
  60. /// <param name="a">first value</param>
  61. /// <param name="b">second value</param>
  62. /// <returns>The hypotenuse Sqrt(a^2 + b^2)</returns>
  63. public static double Hypotenuse(double a, double b)
  64. {
  65. double r = 0.0;
  66. double absA = System.Math.Abs(a);
  67. double absB = System.Math.Abs(b);
  68. if (absA > absB)
  69. {
  70. r = b / a;
  71. r = absA * System.Math.Sqrt(1 + r * r);
  72. }
  73. else if (b != 0)
  74. {
  75. r = a / b;
  76. r = absB * System.Math.Sqrt(1 + r * r);
  77. }
  78. return r;
  79. }
  80. /// <summary>
  81. /// Gets the proper modulus operation for
  82. /// a integer x and modulo m.
  83. /// </summary>
  84. public static int Mod(int x, int m)
  85. {
  86. if (m < 0) m = -m;
  87. int r = x % m;
  88. return r < 0 ? r + m : r;
  89. }
  90. /// <summary>
  91. /// Converts the value x (which is measured in the scale
  92. /// 'from') to another value measured in the scale 'to'.
  93. /// </summary>
  94. public static int Scale(this IntRange from, IntRange to, int x)
  95. {
  96. if (from.Length == 0) return 0;
  97. return (to.Length) * (x - from.Min) / from.Length + to.Min;
  98. }
  99. /// <summary>
  100. /// Converts the value x (which is measured in the scale
  101. /// 'from') to another value measured in the scale 'to'.
  102. /// </summary>
  103. public static double Scale(this DoubleRange from, DoubleRange to, double x)
  104. {
  105. if (from.Length == 0) return 0;
  106. return (to.Length) * (x - from.Min) / from.Length + to.Min;
  107. }
  108. /// <summary>
  109. /// Converts the value x (which is measured in the scale
  110. /// 'from') to another value measured in the scale 'to'.
  111. /// </summary>
  112. public static double Scale(double fromMin, double fromMax, double toMin, double toMax, double x)
  113. {
  114. if (fromMax - fromMin == 0) return 0;
  115. return (toMax - toMin) * (x - fromMin) / (fromMax - fromMin) + toMin;
  116. }
  117. /// <summary>
  118. /// Returns the hyperbolic arc cosine of the specified value.
  119. /// </summary>
  120. public static double Acosh(double x)
  121. {
  122. if (x < 1.0)
  123. throw new ArgumentOutOfRangeException("x");
  124. return System.Math.Log(x + System.Math.Sqrt(x * x - 1));
  125. }
  126. /// <summary>
  127. /// Returns the hyperbolic arc sine of the specified value.
  128. /// </summary>
  129. public static double Asinh(double d)
  130. {
  131. double x;
  132. int sign;
  133. if (d == 0.0)
  134. return d;
  135. if (d < 0.0)
  136. {
  137. sign = -1;
  138. x = -d;
  139. }
  140. else
  141. {
  142. sign = 1;
  143. x = d;
  144. }
  145. return sign * System.Math.Log(x + System.Math.Sqrt(x * x + 1));
  146. }
  147. /// <summary>
  148. /// Returns the hyperbolic arc tangent of the specified value.
  149. /// </summary>
  150. public static double Atanh(double d)
  151. {
  152. if (d > 1.0 || d < -1.0)
  153. throw new ArgumentOutOfRangeException("d");
  154. return 0.5 * System.Math.Log((1.0 + d) / (1.0 - d));
  155. }
  156. /// <summary>
  157. /// Returns the factorial falling power of the specified value.
  158. /// </summary>
  159. public static int FactorialPower(int value, int degree)
  160. {
  161. int t = value;
  162. for (int i = 0; i < degree; i++)
  163. t *= degree--;
  164. return t;
  165. }
  166. /// <summary>
  167. /// Truncated power function.
  168. /// </summary>
  169. public static double TruncatedPower(double value, double degree)
  170. {
  171. double x = System.Math.Pow(value, degree);
  172. return (x > 0) ? x : 0.0;
  173. }
  174. }
  175. /// <summary>
  176. /// Directions for the General Comparer.
  177. /// </summary>
  178. public enum ComparerDirection
  179. {
  180. /// <summary>
  181. /// Sorting will be performed in ascending order.
  182. /// </summary>
  183. Ascending,
  184. /// <summary>
  185. /// Sorting will be performed in descending order.
  186. /// </summary>
  187. Descending
  188. };
  189. /// <summary>
  190. /// General comparer which supports multiple directions
  191. /// and comparison of absolute values.
  192. /// </summary>
  193. public class GeneralComparer : IComparer<double>
  194. {
  195. private bool absolute;
  196. private int direction = 1;
  197. /// <summary>
  198. /// Constructs a new General Comparer.
  199. /// </summary>
  200. /// <param name="direction">The direction to compare.</param>
  201. public GeneralComparer(ComparerDirection direction)
  202. : this(direction, false)
  203. {
  204. }
  205. /// <summary>
  206. /// Constructs a new General Comparer.
  207. /// </summary>
  208. /// <param name="direction">The direction to compare.</param>
  209. /// <param name="useAbsoluteValues">True to compare absolute values, false otherwise. Default is false.</param>
  210. public GeneralComparer(ComparerDirection direction, bool useAbsoluteValues)
  211. {
  212. this.direction = (direction == ComparerDirection.Ascending) ? 1 : -1;
  213. this.absolute = useAbsoluteValues;
  214. }
  215. /// <summary>
  216. /// Compares two objects and returns a value indicating whether one is less than,
  217. /// equal to, or greater than the other.
  218. /// </summary>
  219. /// <param name="x">The first object to compare.</param>
  220. /// <param name="y">The second object to compare.</param>
  221. public int Compare(double x, double y)
  222. {
  223. if (absolute)
  224. return direction * (System.Math.Abs(x).CompareTo(System.Math.Abs(y)));
  225. else
  226. return direction * (x.CompareTo(y));
  227. }
  228. }
  229. }