Guest User

Untitled

a guest
May 24th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.78 KB | None | 0 0
  1. public class PolyNomial
  2. {
  3. public int[] _coefficients;
  4. public PolyNomial()
  5. {
  6. }
  7. public PolyNomial(int degree)
  8. {
  9. _coefficients = new int[degree];
  10. }
  11. public PolyNomial(params int[] coeffs)
  12. {
  13. _coefficients = new int[coeffs.Length];
  14. var i = 0;
  15. foreach (var v in coeffs)
  16. _coefficients[i++] = v;
  17. }
  18. public PolyNomial(PolyNomial p)
  19. {
  20. _coefficients = new int[p.Degree];
  21. for (var i = 0; i < p.Degree; i++)
  22. _coefficients[i] = p._coefficients[i];
  23. }
  24. public PolyNomial(string binary)
  25. {
  26. _coefficients = new int[binary.Length];
  27. var coeffs = new int[binary.Length];
  28. var rb = binary.ToArray();
  29. var n = 0;
  30. for (var p = 0; p < rb.Count(); p++)
  31. {
  32. if (rb[p] == '1')
  33. coeffs[p] = 1;
  34. if (rb[p] == '0')
  35. coeffs[p] = 0;
  36. }
  37. var i = 0;
  38. foreach (var v in coeffs)
  39. _coefficients[i++] = v;
  40. }
  41. public PolyNomial(BigInteger bi)
  42. {
  43. var binary = bi.ToBinaryString();
  44. _coefficients = new int[binary.Length];
  45. var coeffs = new int[binary.Length];
  46. var rb = binary.ToArray();
  47. var n = 0;
  48. for (var p = 0; p < rb.Count(); p++)
  49. {
  50. if (rb[p] == '1')
  51. coeffs[p] = 1;
  52. if (rb[p] == '0')
  53. coeffs[p] = 0;
  54. }
  55. var i = 0;
  56. foreach (var v in coeffs)
  57. _coefficients[i++] = v;
  58. }
  59. public int this[int n] => n < _coefficients.Length ? _coefficients[n] : 0;
  60. public int Degree => _coefficients.Length;
  61. private static PolyNomial AddSubXor(PolyNomial poly1, PolyNomial poly2)
  62. {
  63. var n = Math.Min(poly1.Degree, poly2.Degree);
  64. var coeffs = new int[n];
  65. for (var i = 0; i < n; i++)
  66. coeffs[i] = poly1[i] ^ poly2[i];
  67. return new PolyNomial(coeffs);
  68. }
  69. public PolyNomial BigIntegerToPoly(BigInteger val)
  70. {
  71. var mc = 0;
  72. for (mc = 0; mc < 10240; ++mc)
  73. if ((BigInteger) 1 << mc > val)
  74. break;
  75. var coeffs = new int[mc];
  76. for (var i = 0; i < mc; i++)
  77. {
  78. var mask = (BigInteger) 1 << i;
  79. coeffs[i] = (int) ((val & mask) >> i);
  80. }
  81. coeffs = Reverse(coeffs);
  82. return new PolyNomial(coeffs);
  83. }
  84. public static PolyNomial Builder(PolyNomial p, int index, int dig)
  85. {
  86. if (p._coefficients == null)
  87. p._coefficients = new int[1];
  88. if (index > p.Degree + 1)
  89. throw new Exception("Builder can only be used to add/modify one digit at a time.");
  90. var add = p.Degree;
  91. if (index > p.Degree - 1)
  92. add = p.Degree + 1;
  93. var np = new PolyNomial(add);
  94. for (var i = 0; i < p.Degree; i++)
  95. np._coefficients[i] = p._coefficients[i];
  96. np._coefficients[index] = dig;
  97. return np;
  98. }
  99. public void Clear(PolyNomial p)
  100. {
  101. for (var i = 0; i < p.Degree; ++i)
  102. p._coefficients[i] = 0;
  103. }
  104. public static PolyNomial Clone(PolyNomial p, int newdegree = 0)
  105. {
  106. var size = p.Degree;
  107. if (newdegree != 0)
  108. size = newdegree;
  109. var np = new PolyNomial(size);
  110. for (var i = 0; i < size; i++)
  111. np._coefficients[i] = p._coefficients[i];
  112. return np;
  113. }
  114. public static PolyNomial Concat(PolyNomial p, int dig)
  115. {
  116. var np = new PolyNomial(p.Degree + 1);
  117. for (var i = 0; i < p.Degree; i++)
  118. np._coefficients[i] = p._coefficients[i];
  119. np._coefficients[np.Degree - 1] = dig;
  120. return np;
  121. }
  122. public static PolyNomial CopyFromMsb(PolyNomial p, int digits)
  123. {
  124. var coeffs = new int[digits];
  125. for (var i = 0; i < digits; ++i)
  126. coeffs[i] = p._coefficients[i];
  127. return new PolyNomial(coeffs);
  128. }
  129. public bool Equals(PolyNomial poly1, PolyNomial poly2)
  130. {
  131. if (poly1 == null)
  132. return false;
  133. if (poly2 == null)
  134. return false;
  135. if (poly1.Degree != poly2.Degree)
  136. return false;
  137. for (var i = 0; i < poly1.Degree; i++)
  138. if (poly1._coefficients[i] != poly2._coefficients[i])
  139. return false;
  140. return true;
  141. }
  142. public int GetParity(PolyNomial p)
  143. {
  144. var parity = p._coefficients[0];
  145. for (var i = 1; i < p.Degree; i++)
  146. parity ^= p._coefficients[i];
  147. return parity;
  148. }
  149. public PolyNomial Invert(PolyNomial p)
  150. {
  151. var T = Clone(p);
  152. for (var i = T.Degree; i >= 0; i--)
  153. switch (T._coefficients[i])
  154. {
  155. case 0:
  156. T._coefficients[i] = 1;
  157. continue;
  158. case 1:
  159. T._coefficients[i] = 0;
  160. break;
  161. }
  162. return T;
  163. }
  164. private static PolyNomial LeftShift(PolyNomial p, int n)
  165. {
  166. var T = new PolyNomial(p.Degree + n);
  167. for (var i = 0; i < p.Degree; i++)
  168. T._coefficients[i] = p._coefficients[i];
  169. T = LeftTrim(T, p.Degree);
  170. return T;
  171. }
  172. public static PolyNomial LeftTrim(PolyNomial p, int minSize)
  173. {
  174. var loc = 0;
  175.  
  176. for (var i = 0; i < p.Degree; ++i)
  177. if (p._coefficients[i] == 1)
  178. {
  179. loc = i;
  180. break;
  181. }
  182. if (p.Degree - loc > minSize)
  183. {
  184. }
  185. var T = new PolyNomial(minSize);
  186. if (loc == p.Degree - 1)
  187. {
  188. T._coefficients[0] = 1;
  189. return T;
  190. }
  191. var ptr = minSize - 1;
  192. for (var i = p.Degree - 1; i >= 0 && ptr >= 0; --i, --ptr)
  193. T._coefficients[ptr] = p._coefficients[i];
  194. return T;
  195. }
  196. public static int MsbDegree(PolyNomial p)
  197. {
  198. var loc = 0;
  199. for (var i = 0; i < p.Degree; ++i)
  200. if (p._coefficients[i] == 1)
  201. {
  202. loc = i;
  203. break;
  204. }
  205. return p.Degree - loc;
  206. }
  207. public static PolyNomial operator +(PolyNomial poly1, PolyNomial poly2)
  208. {
  209. return AddSubXor(poly1, poly2);
  210. }
  211. public static PolyNomial[] operator /(PolyNomial dividend, PolyNomial divisor)
  212. {
  213. var Quotient = new PolyNomial();
  214. var Remainder = new PolyNomial();
  215. var Divisormsbdeg = MsbDegree(divisor);
  216. var Dividendmsbdeg = MsbDegree(dividend);
  217. var q = Divisormsbdeg;
  218. var answer = new PolyNomial[2];
  219. if (Dividendmsbdeg < Divisormsbdeg)
  220. {
  221. answer[0] = Quotient;
  222. answer[1] = divisor;
  223. return answer;
  224. }
  225. if (Dividendmsbdeg >= Divisormsbdeg)
  226. {
  227. Quotient = Builder(Quotient, 0, 1);
  228. Remainder = CopyFromMsb(dividend, divisor.Degree) - divisor;
  229. Remainder = LeftShift(Remainder, 1);
  230. Remainder = Builder(Remainder, divisor.Degree - 1, dividend._coefficients[q++]);
  231. }
  232. else
  233. {
  234. Quotient = Builder(Quotient, 0, 0);
  235. }
  236. var qp = 1;
  237. do
  238. {
  239. var Remaindermsbdeg = MsbDegree(Remainder);
  240. if (Remaindermsbdeg >= Divisormsbdeg)
  241. {
  242. Quotient = Builder(Quotient, qp++, 1);
  243. Remainder = Remainder - divisor;
  244. Remainder = LeftShift(Remainder, 1);
  245. Remainder = Builder(Remainder, divisor.Degree - 1, dividend._coefficients[q++]);
  246. }
  247. else
  248. {
  249. Quotient = Builder(Quotient, qp++, 0);
  250. Remainder = Remainder - new PolyNomial(divisor.Degree);
  251. Remainder = LeftShift(Remainder, 1);
  252. if (q < Dividendmsbdeg)
  253. Remainder = Builder(Remainder, divisor.Degree - 1, dividend._coefficients[q++]);
  254. }
  255. } while (q < Dividendmsbdeg);
  256. if (MsbDegree(Remainder) >= Divisormsbdeg)
  257. {
  258. Quotient = Concat(Quotient, 1);
  259. Remainder = Remainder - divisor;
  260. Remainder = TrimNonMsb(Remainder);
  261. }
  262. answer[0] = Quotient;
  263. answer[1] = Remainder;
  264. return answer;
  265. }
  266. public static PolyNomial operator ^(PolyNomial poly1, PolyNomial poly2)
  267. {
  268. return AddSubXor(poly1, poly2);
  269. }
  270. public static PolyNomial operator <<(PolyNomial p, int shift)
  271. {
  272. return LeftShift(p, shift);
  273. }
  274.  
  275. public static PolyNomial operator *(PolyNomial poly1, PolyNomial poly2)
  276. {
  277. var n = Math.Min(poly1.Degree, poly2.Degree);
  278. var coeffs = new int[n];
  279. for (var i = 0; i < n; i++)
  280. if (poly1[i] == 1 && poly2[i] == 1)
  281. coeffs[i] = 1;
  282. else
  283. coeffs[i] = 0;
  284. return new PolyNomial(coeffs);
  285. }
  286. public static PolyNomial operator -(PolyNomial poly1, PolyNomial poly2)
  287. {
  288. return AddSubXor(poly1, poly2);
  289. }
  290. private static int[] Reverse(int[] a)
  291. {
  292. var n = 0;
  293. var T = new int[a.Length];
  294. for (var i = a.Length - 1; i >= 0; i--)
  295. T[n++] = a[i];
  296. return T;
  297. }
  298. public BigInteger ToBigInteger(PolyNomial p)
  299. {
  300. BigInteger Dec = 0;
  301. var T = Clone(p);
  302. T._coefficients = Reverse(T._coefficients);
  303. for (var i = T.Degree - 1; i >= 0; --i)
  304. if (T._coefficients[i] == 1)
  305. Dec += (BigInteger) 1 << i;
  306. return Dec;
  307. }
  308. public string ToBinaryString(PolyNomial p)
  309. {
  310. var sb = new StringBuilder();
  311. var T = Clone(p);
  312. for (var i = 0; i < T.Degree; i++)
  313. sb.Append(T._coefficients[i] == 1 ? "1" : "0");
  314. return sb.ToString();
  315. }
  316. public override string ToString()
  317. {
  318. var T = Clone(this);
  319. T._coefficients = Reverse(_coefficients);
  320. switch (T.Degree)
  321. {
  322. case 0:
  323. return "";
  324. case 1:
  325. return $"{ToBinaryString(this)}," + "x + " + T._coefficients[0];
  326. }
  327. var s = "";
  328. for (var i = T.Degree - 1; i >= 0; i--)
  329. {
  330. if (T._coefficients[i] == 0)
  331. continue;
  332. if (T._coefficients[i] > 0)
  333. {
  334. if (s != "")
  335. s += " + " + T._coefficients[i];
  336. else
  337. s += T._coefficients[i];
  338. }
  339. if (i == 1)
  340. s += "x";
  341. else
  342. if (i > 1)
  343. s += "x^" + i;
  344. }
  345. var rs = s;
  346. try
  347. {
  348. if (T._coefficients.Length <= 64)
  349. rs = $"{ToBinaryString(this)}," + s;
  350. else
  351. rs = $"{ToBinaryString(this)}," + s;
  352. }
  353. catch (Exception)
  354. {
  355. rs = s;
  356. }
  357. return rs;
  358. }
  359. public ulong ToUInt64(PolyNomial p)
  360. {
  361. if (p.Degree > 64)
  362. throw new Exception("Polynomial coefficients array length exceeds 64 bit math.");
  363. ulong Dec = 0;
  364. var T = Clone(p);
  365. T._coefficients = Reverse(T._coefficients);
  366. for (var i = T.Degree - 1; i >= 0; --i)
  367. if (T._coefficients[i] == 1)
  368. Dec += (ulong) (1 << i);
  369. return Dec;
  370. }
  371. public static PolyNomial TrimNonMsb(PolyNomial p)
  372. {
  373. var loc = 0;
  374.  
  375. for (var i = 0; i < p.Degree; ++i)
  376. if (p._coefficients[i] == 1)
  377. {
  378. loc = i;
  379. break;
  380. }
  381. var T = new PolyNomial(p.Degree - loc);
  382. if (loc == p.Degree - 1)
  383. {
  384. T._coefficients[0] = 1;
  385. return T;
  386. }
  387.  
  388. for (var i = loc; i < p.Degree; ++i)
  389. T._coefficients[i - loc] = p._coefficients[i];
  390. return T;
  391. }
  392. public PolyNomial UInt64ToPoly(ulong ul)
  393. {
  394. var mc = 0;
  395. for (mc = 0; mc < 64; ++mc)
  396. if ((ulong) (1 << mc) > ul)
  397. break;
  398. var coeffs = new int[mc];
  399. for (var i = 0; i < mc; i++)
  400. {
  401. var mask = (ulong) (1 << i);
  402. coeffs[i] = (int) ((ul & mask) >> i);
  403. }
  404. coeffs = Reverse(coeffs);
  405. return new PolyNomial(coeffs);
  406. }
  407. }
Add Comment
Please, Sign In to add comment