CpuCalc.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. using FxpConvert.Common;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Runtime.CompilerServices;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. namespace BaseCpuFxpConvert
  8. {
  9. public sealed class CpuCalc : ICalc
  10. {
  11. public IAdd Add { get; } = new CpuAdd();
  12. public ISubtract Subtract { get; } = new CpuSubtract();
  13. public IMultiply Multiply { get; } = new CpuMultiply();
  14. public IDivision Division { get; } = new CpuDivision();
  15. public IFFT FFT { get; } = new CpuFFT();
  16. public IArraySum Sum { get; } = new CpuArraySum();
  17. public unsafe void Fill(ref float result, float value, uint count)
  18. {
  19. if (count == 0) return;
  20. if(value ==0)
  21. {
  22. Unsafe.InitBlock(ref Unsafe.As<float, byte>(ref result), 0, count * 4);
  23. return;
  24. }
  25. Span<float> temp = new Span<float>(Unsafe.AsPointer(ref result),(int)count);
  26. temp.Fill(value);
  27. }
  28. }
  29. public sealed class CpuArraySum : IArraySum
  30. {
  31. public unsafe float Rms(ref float value, uint count)
  32. {
  33. if (count == 0) return 0;
  34. if (count == 1) return value;
  35. float temp = value*value;
  36. float* ptr = (float*)Unsafe.AsPointer(ref value);
  37. for(int i=1;i<count;i++)
  38. {
  39. temp += (ptr[i] * ptr[i]);
  40. }
  41. return MathF.Sqrt(temp / count);
  42. }
  43. public unsafe double Rms(ref double value, uint count)
  44. {
  45. if (count == 0) return 0;
  46. if (count == 1) return value;
  47. double temp = value * value;
  48. double* ptr = (double*)Unsafe.AsPointer(ref value);
  49. for (int i = 1; i < count; i++)
  50. {
  51. temp += (ptr[i] * ptr[i]);
  52. }
  53. return Math.Sqrt(temp / count);
  54. }
  55. public unsafe float Sum(ref float value, uint count)
  56. {
  57. if (count == 0) return 0;
  58. if (count == 1) return value;
  59. float* ptr = (float*)Unsafe.AsPointer(ref value);
  60. float temp = value;
  61. for(int i=1;i<count;i++)
  62. {
  63. temp += ptr[i];
  64. }
  65. return temp;
  66. }
  67. public unsafe double Sum(ref double value,uint count)
  68. {
  69. if (count == 0) return 0;
  70. if(count ==1)return value;
  71. double* ptr = (double*)Unsafe.AsPointer(ref value);
  72. double temp = value;
  73. for(int i=1;i<count;i++)
  74. {
  75. temp += ptr[i];
  76. }
  77. return temp;
  78. }
  79. }
  80. public sealed class CpuFFT:IFFT
  81. {
  82. public void FFT(double[] real, double[] imaginary)
  83. {
  84. MathNet.Numerics.IntegralTransforms.Fourier.Forward(real, imaginary, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
  85. }
  86. public void FFT(float[] real, float[] imaginary)
  87. {
  88. MathNet.Numerics.IntegralTransforms.Fourier.Forward(real, imaginary, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
  89. }
  90. }
  91. public sealed class CpuSubtract : ISubtract
  92. {
  93. public void Subtract(ref float left, float right, uint count, ref float result)
  94. {
  95. if (count == 0) return;
  96. for (int i = 0; i < count; i++)
  97. {
  98. ref float temp = ref Unsafe.Add(ref result, i);
  99. temp = Unsafe.Add(ref left, i) - right;
  100. }
  101. }
  102. public void Subtract(ref float left, ref float right, uint count, ref float result)
  103. {
  104. if (count == 0) return;
  105. for (int i = 0; i < count; i++)
  106. {
  107. ref float temp = ref Unsafe.Add(ref result, i);
  108. temp = Unsafe.Add(ref left, i) - Unsafe.Add(ref right, i);
  109. }
  110. }
  111. public void Subtract(ref float left, float right, uint count)
  112. {
  113. if (count == 0) return;
  114. for (int i = 0; i < count; i++)
  115. {
  116. ref float temp = ref Unsafe.Add(ref left, i);
  117. temp -= right;
  118. }
  119. }
  120. public void Subtract(ref float left, ref float right, uint count)
  121. {
  122. if (count == 0) return;
  123. for (int i = 0; i < count; i++)
  124. {
  125. ref float temp = ref Unsafe.Add(ref left, i);
  126. temp -= Unsafe.Add(ref right, i);
  127. }
  128. }
  129. }
  130. public sealed class CpuAdd:IAdd
  131. {
  132. public void Add(ref float left, float right, uint count, ref float result)
  133. {
  134. if (count == 0) return;
  135. for (int i = 0; i < count; i++)
  136. {
  137. ref float temp = ref Unsafe.Add(ref result, i);
  138. temp = Unsafe.Add(ref left, i) + right;
  139. }
  140. }
  141. public void Add(ref float left, ref float right, uint count, ref float result)
  142. {
  143. if (count == 0) return;
  144. for (int i = 0; i < count; i++)
  145. {
  146. ref float temp = ref Unsafe.Add(ref result, i);
  147. temp = Unsafe.Add(ref left, i) + Unsafe.Add(ref right, i);
  148. }
  149. }
  150. public void Add(ref float left, float right, uint count)
  151. {
  152. if (count == 0) return;
  153. for (int i = 0; i < count; i++)
  154. {
  155. ref float temp = ref Unsafe.Add(ref left, i);
  156. temp += right;
  157. }
  158. }
  159. public void Add(ref float left, ref float right, uint count)
  160. {
  161. if (count == 0) return;
  162. for (int i = 0; i < count; i++)
  163. {
  164. ref float temp = ref Unsafe.Add(ref left, i);
  165. temp += Unsafe.Add(ref right, i);
  166. }
  167. }
  168. }
  169. public sealed class CpuMultiply : IMultiply
  170. {
  171. public void Multiply(ref float left, float right, uint count, ref float result)
  172. {
  173. if (count == 0) return;
  174. for (int i = 0; i < count; i++)
  175. {
  176. ref float temp = ref Unsafe.Add(ref result, i);
  177. temp = Unsafe.Add(ref left, i) * right;
  178. }
  179. }
  180. public void Multiply(ref float left, ref float right, uint count, ref float result)
  181. {
  182. if (count == 0) return;
  183. for (int i = 0; i < count; i++)
  184. {
  185. ref float temp = ref Unsafe.Add(ref result, i);
  186. temp = Unsafe.Add(ref left, i) * Unsafe.Add(ref right, i);
  187. }
  188. }
  189. public void Multiply(ref float left, float right, uint count)
  190. {
  191. if (count == 0) return;
  192. for (int i = 0; i < count; i++)
  193. {
  194. ref float temp = ref Unsafe.Add(ref left, i);
  195. temp *= right;
  196. }
  197. }
  198. public void Multiply(ref float left, ref float right, uint count)
  199. {
  200. if (count == 0) return;
  201. for (int i = 0; i < count; i++)
  202. {
  203. ref float temp = ref Unsafe.Add(ref left, i);
  204. temp *= Unsafe.Add(ref right, i);
  205. }
  206. }
  207. }
  208. public sealed class CpuDivision : IDivision
  209. {
  210. public void Division(ref float left, float right, uint count, ref float result)
  211. {
  212. if (count == 0) return;
  213. for (int i = 0; i < count; i++)
  214. {
  215. ref float temp = ref Unsafe.Add(ref result, i);
  216. temp = Unsafe.Add(ref left, i) / right;
  217. }
  218. }
  219. public void Division(ref float left, ref float right, uint count, ref float result)
  220. {
  221. if (count == 0) return;
  222. for (int i = 0; i < count; i++)
  223. {
  224. ref float temp = ref Unsafe.Add(ref result, i);
  225. temp = Unsafe.Add(ref left, i) / Unsafe.Add(ref right, i);
  226. }
  227. }
  228. public void Division(ref float left, float right, uint count)
  229. {
  230. if (count == 0) return;
  231. for (int i = 0; i < count; i++)
  232. {
  233. ref float temp = ref Unsafe.Add(ref left, i);
  234. temp /= right;
  235. }
  236. }
  237. public void Division(ref float left, ref float right, uint count)
  238. {
  239. if (count == 0) return;
  240. for (int i = 0; i < count; i++)
  241. {
  242. ref float temp = ref Unsafe.Add(ref left, i);
  243. temp /= Unsafe.Add(ref right, i);
  244. }
  245. }
  246. }
  247. }